SQL – SI EXISTE ACTUALIZACIÓN MÁS INSERT INTO

Lo que yo estoy tratando de hacer es INSERT de suscriptores en mi base de datos, pero IF EXISTS debe UPDATE la fila, ELSE INSERT INTO una nueva fila.

Por supuesto me puedo conectar a la base de datos primero y GET la $name, $email y $birthday de la cadena de dirección url.

$con=mysqli_connect("localhost","---","---","---");
// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

$name=$_GET['name']; 
$email=$_GET['email'];
$birthday=$_GET['birthday'];

Esto funciona, pero sólo añade la nueva fila;

mysqli_query($con,"INSERT INTO subs (subs_name, subs_email, subs_birthday)
VALUES ('$name', '$email', '$birthday')");

mysqli_close($con);

Aquí es lo que he intentado;

mysqli_query($con,"INSERT INTO subs (subs_name, subs_email, subs_birthday)
VALUES '$name', '$email', '$birthday'
ON DUPLICATE KEY UPDATE subs_name = VALUES($name), subs_birthday = VALUES($birthday)");
mysqli_close($con);

y

mysqli_query($con,"IF EXISTS (SELECT * FROM subs WHERE subs_email='$email')
    UPDATE subs SET subs_name='$name', subs_birthday='$birthday' WHERE subs_email='$email'
ELSE
    INSERT INTO subs (subs_name, subs_email, subs_birthday) VALUES ('$name', '$email', '$birthday')");
mysqli_close($con);

y

mysqli_query($con,"IF NOT EXISTS(SELECT * FROM subs WHERE subs_email='$email')
Begin
INSERT INTO subs (subs_name, subs_email, subs_birthday)
VALUES ('$name', '$email', '$birthday')
End");
mysqli_close($con);

Pero ninguno de ellos funciona, ¿qué estoy haciendo mal?

Cualquier ayuda es muy apreciada!

1 Kommentar

  1. 186
    1. Crear un ÚNICO restricción en su subs_email de la columna, si no existe ya uno:

      ALTER TABLE subs ADD UNIQUE (subs_email)
    2. Uso INSERTAR ... EN CLAVE DUPLICADA ACTUALIZACIÓN:

      INSERT INTO subs
        (subs_name, subs_email, subs_birthday)
      VALUES
        (?, ?, ?)
      ON DUPLICATE KEY UPDATE
        subs_name     = VALUES(subs_name),
        subs_birthday = VALUES(subs_birthday)

    Puede utilizar los VALORES(col_name) en función de la cláusula de ACTUALIZACIÓN para
    se refieren a los valores de la columna de la INSERCIÓN de la porción de la INSERCIÓN EN …
    DUPLICATE KEY UPDATE – dev.mysql.com

    1. Nota que he usado parámetro marcadores de posición en el lugar de los literales de cadena, como una realmente debe parametrizarse mediante declaraciones a defenderse de los ataques de inyección SQL.
    • Usted da Man! Funciona como un encanto, ahora a encontrar una manera de proteger a este en contra de las inyecciones. Estoy enviando los datos a la base de datos después de que las personas han confirmado su suscripción al boletín de noticias, con los parámetros publicados en la cadena. Alguna idea de cómo asegurar esto? Thnx
    • Ver a mi tercer punto, sobre todo la respuesta a la que se vincula.
    • fok este es cewl! He estado usando MySQL bastante tiempo ahora, y nunca utilizado esto!
    • Acabo de probar esto y no tengo que usar VALUES() en el UPDATE declaración.
    • Pero si InnoDB Spa se utiliza, el incremento automático de identificación crecerá loco rápido.
    • impresionante @eggyal
    • podemos usar mysql función definida por el usuario en los VALORES de()?
    • Seguro, ¿por qué no?
    • Yo no soy capaz, me dice error de Sintaxis. Así que tuvo que declarar una variable y almacenar la función devuelve el valor y el uso que la variable dentro de los VALORES de()
    • Ah, perdón, pensé que significaba en el VALUES() cláusula. El VALUES() función sólo se necesita el nombre de la columna cuyo valor de la VALUES() cláusula que desea usar: es simplemente un atajo para evitar la repetición de sí mismo; usted no tiene que usarlo. Usted puede simplemente utilizar directamente la función en el SET cláusula si desea, por ejemplo, la SET column = MYFUNCTION().
    • ¿Por qué no utilizar «REEMPLAZAR EN» en lugar de ( o a fusionarse para db2 ) ? parece más fácil y más rápido.
    • elimina el registro de edad (con cualquier FK y desencadenar consecuencias), a continuación, inserta una nueva (otra vez con efectos secundarios); por otra parte, debido a que el nuevo registro especificado por los valores dados en la REPLACE declaración, cualquier omitido las columnas se establecen en sus valores predeterminados (mientras que las actualizaciones anteriores sólo las columnas especificadas, dejando todo lo demás sin tocar). No estoy seguro de dónde sacó la idea de que REPLACE es más rápido, ya que una actualización debe siempre superar a eliminar & insert. Como más fácil, REPLACE todavía requiere una restricción unique ser definido…
    • Mmmh que tiene sentido, acabo de leer un artículo acerca de que, tal vez, el artículo está equivocado. percona.com/blog/2010/07/14/…
    • ¿Y qué acerca de la COMBINACIÓN EN la que parece proceder de una real actualizar o insertar nuevo ? buen ejemplo aquí, stackoverflow.com/questions/15701327/…
    • Que interesante artículo, profundizando en algunos de muy bajo nivel de detalles de MySQL es el motor de almacenamiento API que yo no sabía nada—gracias por traerme a la velocidad. Sin embargo, yo todavía prefieren expresar mi lógica deseada, tan claramente como sea posible para ayudar a los futuros mantenimiento: sólo si las otras preocupaciones mencionadas anteriormente a suceder, no ser relevante, y que está causando el rendimiento del material de impacto habría de considerar el cambio a REPLACE cuando realmente se tiene la intención de actualizar. Recuerde Knuth la máxima de: «optimización prematura es la raíz de todo mal».
    • Como para MERGE INTO—esta pregunta fue acerca de MySQL, que no es compatible con ese comando. Su rendimiento en otros sistemas serán dependientes de la implementación.
    • ME DA UN ERROR!
    • SQLSTATE[42000]: error de Sintaxis o de infracción de acceso: 1064 Usted tiene un error en la sintaxis de SQL; consulte el manual que corresponde a la versión del servidor MySQL para la sintaxis para usar cerca de «AJAY KUMAR’)’ en la línea 2 El SQL se ejecuta era: INSERT INTO fee_acc_balance (guardian_name, account_no, paid_amount, debido, days_overdue, total_fees, updated_on) VALUES (‘AJAY KUMAR’, ’10’, 0, 12550, 0, 12550, ‘2017-02-10 21:28:05’) EN el DUPLICADO de la ACTUALIZACIÓN de la CLAVE de guardian_name = VALUES (‘AJAY KUMAR’) Error Info: Array ( [0] => 42000 [1] => 1064 [2] => Usted tiene un error
    • La clave única en mi caso es account_no, y este es mi sql : INSERT INTO fee_acc_balance (guardian_name, account_no, paid_amount, debido, days_overdue, total_fees, updated_on) VALUES (‘$father_name’, ‘cuenta de $->account_no’, $pagos, $suma, 0, $suma, ‘$ahora’) ON DUPLICATE KEY UPDATE guardian_name = VALUES (‘$father_name’)
    • En la finalización de la consulta de cómo averiguar si se trataba de un insert o update?
    • DUPLICATE KEY UPDATE, el afectado-valor de filas por fila es 1 si la fila se inserta una nueva fila, 2 si una fila existente se actualiza, y 0 si una fila existente se ajusta a su valor actual.«
    • Esto no va a funcionar en la consola sql, dar menos si es falsa! 🙂

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea