La Violation de la contrainte de CLÉ PRIMAIRE. Impossible d'insérer une clé en double dans l'objet de SQL Server
J'ai hérité d'un projet et je suis en cours d'exécution dans un SQL
erreur que je ne suis pas sûr de la façon de les corriger.
Sur un site de commerce électronique, le code est l'insertion d'expédition de la commande info dans une autre table de base de données.
Voici le code à insérer les infos dans la table:
string sql = "INSERT INTO AC_Shipping_Addresses
(pk_OrderID, FullName, Company, Address1, Address2, City, Province, PostalCode, CountryCode, Phone, Email, ShipMethod, Charge_Freight, Charge_Subtotal)
VALUES (" + _Order.OrderNumber;
sql += ", '" + _Order.Shipments[0].ShipToFullName.Replace("'", "''") + "'";
if (_Order.Shipments[0].ShipToCompany == "")
{
sql += ", '" + _Order.Shipments[0].ShipToFullName.Replace("'", "''") + "'";
}
else
{
sql += ", '" + _Order.Shipments[0].ShipToCompany.Replace("'", "''") + "'";
}
sql += ", '" + _Order.Shipments[0].Address.Address1.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.Address2.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.City.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.Province.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.PostalCode.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.Country.Name.Replace("'", "''") + "'";
sql += ", '" + _Order.Shipments[0].Address.Phone.Replace("'", "''") + "'";
if (_Order.Shipments[0].ShipToEmail == "")
{
sql += ",'" + _Order.BillToEmail.Replace("'", "''") + "'";
}
else
{
sql += ",'" + _Order.Shipments[0].ShipToEmail.Replace("'", "''") + "'";
}
sql += ", '" + _Order.Shipments[0].ShipMethod.Name.Replace("'", "''") + "'";
sql += ", " + shippingAmount;
sql += ", " + _Order.ProductSubtotal.ToString() + ")";
bll.dbUpdate(sql);
Qu'il fonctionne correctement, mais c'est aussi la sortie de la suite SQL error:
Violation de la contrainte de CLÉ PRIMAIRE 'PK_AC_Shipping_Addresses'. Impossible d'insérer
clé en double dans l'objet 'dbo.AC_Shipping_Addresses'. La valeur de clé en double
est (165863).
À partir de la lecture des questions similaires, il semble que je devrais déclarer l'ID dans la déclaration.
Est-ce exact? Comment puis-je ajuster le code pour résoudre ce problème?
Toute aide est grandement appréciée!
Étape 1) connaître la valeur de
sql
est avant l'exécution. Étape 0) Changement à l'aide de valeurs de liaison pour la requête au lieu de concaténation. Google "SQL Injection" pour la raison du pourquoi.Quelle est la valeur que vous êtes en passant à la clé primaire (sans doute "pk_OrderID")? Vous pouvez le configurer à l'auto incrément, et alors il ne devrait jamais être un problème avec la duplication de la valeur de la DB prendra soin de cela. Si vous devez spécifier une valeur pour vous-même, vous aurez besoin d'écrire du code pour déterminer quelle est la valeur max pour que le terrain est, et puis incrémenter.
quel est votre champ de clé unique? on dirait que votre OrderNumber est en double, vous pouvez déjà avoir le n ° d'ordre 165863 dans votre table et que vous essayez d'insérer un duplciate
Si la valeur de clé primaire existe déjà, alors vous pouvez simplement mettre à jour ou vous aurez à supprimer l'état de la valeur avant d'en insérer une nouvelle:
string sql = "DELETE FROM AC_Shipping_Addresses where pk_OrderID = " + _Order.OrderNumber;
OriginalL'auteur Justin Hollender | 2016-03-16
Vous devez vous connecter pour publier un commentaire.
Assez sûr pk_OrderID est le PK de AC_Shipping_Addresses
Et que vous essayez d'insérer un duplicata via le _Order.OrderNumber
Faire un
ou select count(*) ....
Assez sûr que vous obtiendrez une ligne retournée.
Ce qu'il vous dit, c'est que vous utilisez déjà pk_OrderID = 165863 et ne peut pas avoir une autre ligne avec cette valeur.
si vous ne voulez pas insérer si il y a une rangée
Oui, en théorie, cela pourrait fonctionner. Mais je ajouter quelque chose que j'aime le mieux.
OriginalL'auteur paparazzo
J'avais la même erreur sur une base de données restaurée lorsque j'ai essayé d'insérer un nouvel enregistrement en utilisant la EntityFramework. Il s'est avéré que l'Identité/les Semences de vissage les choses.
À l'aide d'un réamorçage de commande fixe.
OriginalL'auteur Ger Groot
Quelle est la valeur que vous êtes en passant à la clé primaire (sans doute "pk_OrderID")? Vous pouvez le configurer à l'auto incrément, et alors il ne devrait jamais être un problème avec la duplication de la valeur de la DB prendra soin de cela. Si vous devez spécifier une valeur pour vous-même, vous aurez besoin d'écrire du code pour déterminer quelle est la valeur max pour que le terrain est, et puis incrémenter.
Si vous avez une colonne nommée "ID" ou telle qui ne figure pas dans la requête, c'est très bien tant qu'il est mis en place pour autoincrement - mais sans doute pas, ou vous ne devriez pas obtenir ce message d'erreur. Aussi, vous feriez mieux de l'écriture d'un plus facile sur les yeux de la requête et à l'aide de paramètres. Le garçon de neuf ans, donc en déduire que vous êtes en laissant votre base de données ouverte à des attaques par injection SQL si vous avez simplement plop dans les valeurs entrées par l'utilisateur. Par exemple, vous pourriez avoir une méthode comme ceci:
...qui est appelé de la sorte:
Vous n'avez pas à, mais je stocker la requête séparément:
Vous pouvez vérifier que vous n'êtes pas sur le point d'insertion d'une valeur existante par (pseudo-code):
La requête est quelque chose comme "SELECT COUNT from TABLE where BLA = @CANDIDATEIDVAL" et la valeur de l'ID que vous êtes potentiellement sujet à insérer:
Justin veut savoir si cela va fonctionner:
Ce qui semble serait de travailler pour moi, c'est:
Oui, vérifiez que la valeur dans le tableau, vous êtes sur le point de les insérer dans la; si elle existe, inc le nombre. Vous pourriez avoir besoin de garder le contrôle jusqu'à ce que vous trouver un nombre qui n'existe pas déjà.
Pour vérifier la valeur, serait-ce l'énoncé correct? bool alreadyExists = IDAlreadyExists(SELECT COUNT(*) from AC_Shipping_Addresses où pk_OrderID = _Order.OrderNumber, _Order.OrderNumber) > 0;
Cela devrait être suffisant: "SELECT COUNT(*) from AC_Shipping_Addresses où pk_OrderID = _Order.OrderNumber"
Désolé, je n'ai jamais écrit un if/else avec des requêtes SQL avant. Serait-ce comme cela? si ("SELECT COUNT(*) from AC_Shipping_Addresses où pk_OrderID = _Order.OrderNumber" != 0) { //insérez } l'instruction return 0 ou NULL si il n'y a pas une valeur correspondante?
OriginalL'auteur B. Clay Shannon
Pour empêcher l'insertion d'un enregistrement qui existent déjà. J'aimerais vérifier si la valeur de l'ID existe dans la base de données. Pour l'exemple d'un Tableau créé avec une IDENTITÉ de CLÉ PRIMAIRE:
Quand JANE DOE et JOE BROWN existent déjà dans la base de données.
BASE de données de SORTIE de la TABLE [dbo].[Les personnes] sera:
Je voudrais vérifier si je devrais mettre à jour un enregistrement existant ou insérez-en une nouvelle. Comme l'exemple JAVA suivant:
OriginalL'auteur QA Specialist
Il peut y avoir plusieurs choses à l'origine de ce et quelque peu dépend de ce que vous avez défini dans votre base de données.
Première, vous pourriez être en utilisant une clé primaire dans la table qui est aussi un FK à une autre table pour faire de la relation 1-1. DANS ce cas, vous devrez peut-être faire une mise à jour plutôt que d'un insert. Si vous avez vraiment ne peut avoir qu'un enregistrement d'adresse pour une commande, c'est peut être ce qui se passe.
Suivant vous pourriez être en utilisant une sorte de processus manuel pour déterminer l'id à l'avance. La difficulté avec ces processus manuels, c'est qu'ils peuvent créer des conditions de course où les deux enregistrements age le même id et l'incrémenter par un, puis la seconde, on peut;t insérer.
Troisième, d'une requête lorsqu'elle est envoyée à la base de données peut être la création de deux enregistrements. Pour déterminer si c'est le cas, Exécutez Profiler pour voir exactement ce que le code SQL que vous envoyez et si ti est un select à la place d'une clause values, puis exécutez le sélectionner et de voir si vous avez raison pour les jointures obtenu quelques enregistrements dupliqués. EN tout, même lorsque vous êtes la création de code à la volée, comme cela la première étape de dépannage est TOUJOURS exécuter le générateur de profils et voir si ce qui l'a envoyé est ce que vous vous attendiez à être envoyé.
OriginalL'auteur HLGEM