php - usuario - validar si existe un registro en oracle
¿Cómo ''insertar si no existe'' en MySQL? (9)
Comencé en Google y encontré este article que habla sobre tablas de exclusión mutua.
Tengo una mesa con ~ 14 millones de registros. Si quiero agregar más datos en el mismo formato, ¿hay alguna manera de asegurar que el registro que quiero insertar no exista sin usar un par de consultas (es decir, una consulta para verificar y otra para insertar es el conjunto de resultados que se obtiene)? vacío)?
¿Una restricción unique
en un campo garantiza que la insert
fallará si ya está allí?
Parece que con solo una restricción, cuando emito el inserto a través de php, el script se agita.
Aquí hay una función de PHP que insertará una fila solo si todos los valores de columnas especificados no existen en la tabla.
Si una de las columnas difiere, se agregará la fila.
Si la tabla está vacía, se agregará la fila.
Si existe una fila donde todas las columnas especificadas tienen los valores especificados, la fila no se agregará.
function insert_unique($table, $vars) { if (count($vars)) { $table = mysql_real_escape_string($table); $vars = array_map(''mysql_real_escape_string'', $vars); $req = "INSERT INTO `$table` (`". join(''`, `'', array_keys($vars)) ."`) "; $req .= "SELECT ''". join("'', ''", $vars) ."'' FROM DUAL "; $req .= "WHERE NOT EXISTS (SELECT 1 FROM `$table` WHERE "; foreach ($vars AS $col => $val) $req .= "`$col`=''$val'' AND "; $req = substr($req, 0, -5) . ") LIMIT 1"; $res = mysql_query($req) OR die(); return mysql_insert_id(); } return False; }
Ejemplo de uso:
<?php
insert_unique(''mytable'', array(
''mycolumn1'' => ''myvalue1'',
''mycolumn2'' => ''myvalue2'',
''mycolumn3'' => ''myvalue3''
)
);
?>
Cualquier restricción simple debe hacer el trabajo, si una excepción es aceptable. Ejemplos:
- clave principal si no es sustituto
- restricción única en una columna
- restricción única de varias columnas
Lo siento es que esto parece engañosamente simple. Sé que se ve mal en el enlace que compartes con nosotros. ;-(
Pero nunca doy esta respuesta, porque parece llenar tu necesidad. (Si no, puede activar la actualización de sus requisitos, lo que también sería "una cosa buena" (TM)).
Editado : si una inserción rompería la restricción única de la base de datos, se lanzará una excepción en el nivel de la base de datos, transmitida por el controlador. Ciertamente detendrá su guión, con un fallo. Debe ser posible en PHP abordar ese caso ...
Hay varias respuestas que cubren cómo resolver esto si tiene un índice UNIQUE
que se puede comparar con ON DUPLICATE KEY
o INSERT IGNORE
. No siempre es así, y como UNIQUE
tiene una restricción de longitud (1000 bytes), es posible que no pueda cambiar eso. Por ejemplo, tuve que trabajar con metadatos en WordPress ( wp_postmeta
).
Finalmente lo resolví con dos consultas:
UPDATE wp_postmeta SET meta_value = ? WHERE meta_key = ? AND post_id = ?;
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) SELECT DISTINCT ?, ?, ? FROM wp_postmeta WHERE NOT EXISTS(SELECT * FROM wp_postmeta WHERE meta_key = ? AND post_id = ?);
La consulta 1 es una consulta de UPDATE
regular sin efecto cuando el conjunto de datos en cuestión no está allí. La consulta 2 es un INSERT
que depende de un NOT EXISTS
, es decir, el INSERT
solo se ejecuta cuando el conjunto de datos no existe.
Intenta lo siguiente:
IF (SELECT COUNT(*) FROM beta WHERE name = ''John'' > 0)
UPDATE alfa SET c1=(SELECT id FROM beta WHERE name = ''John'')
ELSE
BEGIN
INSERT INTO beta (name) VALUES (''John'')
INSERT INTO alfa (c1) VALUES (LAST_INSERT_ID())
END
Tratar:
// Check if exist cod = 56789
include "database.php";
$querycheck = mysql_query ("SELECT * FROM `YOURTABLE` WHERE `xxx` = ''56789'';");
$countrows = mysql_num_rows($querycheck);
if($countrows == ''1'')
{
// Exist
}
else
{
// .... Not exist
}
O puedes hacer:
// Check if exist cod = 56789
include "database.php";
$querycheck = mysql_query ("SELECT * FROM `YOURTABLE` WHERE `xxx` = ''56789'';");
$countrows = mysql_num_rows($querycheck);
while($result = mysql_fetch_array($querycheck))
{
$xxx = $result[''xxx''];
if($xxx == ''56789'')
{
// Exist
}
else
{
// Not exist
}
}
Este método es rápido y fácil. Para mejorar la velocidad de la consulta en su tabla grande INDEX columnas ''xxx'' (en mi ejemplo).
usa la INSERT IGNORE INTO table
ver http://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html
También hay una sintaxis INSERT … ON DUPLICATE KEY UPDATE
, puede encontrar explicaciones en dev.mysql.com
Publica desde bogdan.org.ua de acuerdo con el webcache de Google :
18 de octubre de 2007
Para empezar: a partir de la última versión de MySQL, la sintaxis presentada en el título no es posible. Pero hay varias formas muy fáciles de lograr lo que se espera utilizando la funcionalidad existente.
Hay 3 soluciones posibles: usar INSERT IGNORE, REPLACE, o INSERT ... ON DUPLICATE KEY UPDATE.
Imagina que tenemos una mesa:
CREATE TABLE `transcripts` ( `ensembl_transcript_id` varchar(20) NOT NULL, `transcript_chrom_start` int(10) unsigned NOT NULL, `transcript_chrom_end` int(10) unsigned NOT NULL, PRIMARY KEY (`ensembl_transcript_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Ahora imagine que tenemos una tubería automática que importa metadatos de transcripciones de Ensembl, y que debido a varias razones la tubería se puede romper en cualquier paso de la ejecución. Por lo tanto, debemos garantizar dos cosas: 1) las ejecuciones repetidas de la tubería no destruirán nuestra base de datos, y 2) las ejecuciones repetidas no morirán debido a errores de "clave primaria duplicada".
Método 1: utilizando REEMPLAZAR
Es muy sencillo:
REPLACE INTO `transcripts` SET `ensembl_transcript_id` = ‘ENSORGT00000000001′, `transcript_chrom_start` = 12345, `transcript_chrom_end` = 12678;
Si el registro existe, se sobrescribirá; Si aún no existe, será creado. Sin embargo, usar este método no es eficiente para nuestro caso: no necesitamos sobrescribir los registros existentes, está bien simplemente omitirlos.
Método 2: usando INSERT IGNORE También muy simple:
INSERT IGNORE INTO `transcripts` SET `ensembl_transcript_id` = ‘ENSORGT00000000001′, `transcript_chrom_start` = 12345, `transcript_chrom_end` = 12678;
Aquí, si el ''ensembl_transcript_id'' ya está presente en la base de datos, se omitirá en silencio (se ignorará). (Para ser más precisos, aquí hay una cita del manual de referencia de MySQL: “Si usa la palabra clave IGNORE, los errores que se producen al ejecutar la instrucción INSERT se tratan como advertencias. Por ejemplo, sin IGNORE, una fila que duplica un índice UNIQUE existente o el valor de CLAVE PRIMARIA en la tabla provoca un error de clave duplicada y la declaración se cancela. ".) Si el registro aún no existe, se creará.
Este segundo método tiene varios puntos débiles potenciales, incluido el no aborto de la consulta en caso de que ocurra algún otro problema (consulte el manual). Por lo tanto, debe utilizarse si se probó previamente sin la palabra clave IGNORE.
Hay una opción más: usar la sintaxis INSERTAR ... ACTUALIZAR LA ACTUALIZACIÓN DE LA TECLA DUPLICADA, y en la parte ACTUALIZAR simplemente no hacer nada sin hacer ninguna operación (vacía), como calcular 0 + 0 (Geoffray sugiere hacer la asignación id = id para la optimización de MySQL motor para ignorar esta operación). La ventaja de este método es que solo ignora eventos clave duplicados, y todavía aborta otros errores.
Como último aviso: este post fue inspirado por Xaprb. También aconsejaría consultar su otra publicación sobre la escritura de consultas SQL flexibles.
en la actualización de la clave duplicada , o insertar ignorar pueden ser soluciones viables con MySQL.
Ejemplo de actualización de clave duplicada basada en mysql.com
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
UPDATE table SET c=c+1 WHERE a=1;
Ejemplo de inserción ignorar basado en mysql.com
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
{VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
O:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
SET col_name={expr | DEFAULT}, ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
O:
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
INSERT INTO `table` (value1, value2)
SELECT ''stuff for value1'', ''stuff for value2'' FROM `table`
WHERE NOT EXISTS (SELECT * FROM `table`
WHERE value1=''stuff for value1'' AND value2=''stuff for value2'')
LIMIT 1
Alternativamente, la instrucción SELECT
externa puede referirse a DUAL
para manejar el caso donde la tabla está inicialmente vacía:
INSERT INTO `table` (value1, value2)
SELECT ''stuff for value1'', ''stuff for value2'' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM `table`
WHERE value1=''stuff for value1'' AND value2=''stuff for value2'')
LIMIT 1
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = ''ENSORGT00000000001'',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
Si el registro existe, se sobrescribirá; Si aún no existe, será creado.