2017-08-08 5 views
1

Dies ist meist eine Frage Neugier. Ich habe gerade erlebt eine Situation, wo auf einer Testdatenbank ich die folgende Abfrage hatte:Microsoft SQL Server - Unterabfragen einschränken

update table 
set column1 = 1 
where column2 in (1,2) 

Aber dies hielt mit dem Fehler ausführt, dass Subquery mehr als einen Wert zurückgegeben.

Jetzt habe ich überprüft, um sicherzustellen, dass ich nicht mehrere Identitätsschlüssel hatte oder dass die 'in' Werte eindeutig waren. Also sollte dies in keiner Weise geschehen sein.

Beim Überprüfen der LIVE-Kopie der Datenbank hatte dieselbe Abfrage kein Problem. Meine Frage lautet also:

Was können Sie mit den Microsoft SQL Server-Einstellungen oder der Datenbankstruktur tun, die ein solches Szenario erstellen würde?

+12

Hat Ihre Tabelle einen Update-Trigger? Ich vermute, dass es so ist, und es nimmt an, dass "eingefügt" oder "gelöscht" nur eine Zeile enthält. –

+0

Also ... die einzige Möglichkeit, die PK-Verletzung zu verursachen, ist, wenn die Spalte1 ein Teil der zusammengesetzten PK oder PK selbst ist. Die Abfrage scheint geradlinig zu sein: Aktualisieren Sie Spalte1 und setzen Sie sie auf (1), wenn Sie Wert (1) oder (2) in der Spalte2 innerhalb desselben Tupels finden. Ich schätze deine Test DB hat andere Startaufzeichnungen als deine Produktion. Können Sie die Produktionswerte in Ihre Test-DB kopieren und erneut ausführen? – Milan

+0

@Milan Wie hast du von "Unterabfrage mehr als einen Wert zurückgegeben" zu "PK-Verletzung"? – HABO

Antwort

2

Was können Sie mit den Microsoft SQL Server-Einstellungen oder der Datenbankstruktur tun, die ein solches Szenario erstellen würden?

Wie in Kommentaren erwähnt haben Sie wahrscheinlich schlecht geschrieben Trigger. Beispielszenario:

CREATE TABLE aud(column2 INT, comment NVARCHAR(150)); 
CREATE TABLE tab(column1 INT, column2 INT); 

INSERT INTO aud(column2) VALUES (1),(2),(3); 
INSERT INTO tab(column1, column2) VALUES (0,1),(-1, 2), (-2,3); 
GO 

CREATE TRIGGER trg_tab_i ON tab 
FOR UPDATE 
AS 
BEGIN 
    UPDATE aud 
    SET comment = 'Changed value ...' 
    WHERE column2 = (SELECT column2 FROM inserted); 
END 
GO 


UPDATE tab 
SET column1 = 1 
WHERE column2 in (1,2); 

Msg 512, Ebene 16, Status 1, Prozedur trg_tab_i, Linie 5 [Batch Startlinie 19]

Unterabfrage gab mehr als 1 Wert. Dies ist nicht zulässig, wenn die Unterabfrage folgt =,! =, <, < =,>,> = oder wenn die Unterabfrage als Ausdruck verwendet wird.

UPDATE tab 
SET column1 = 1 
WHERE column2 in (1); 
-- (1 row(s) affected) 
-- (1 row(s) affected) 

DBFiddle Demo

Wenn nur eine Zeile alles betroffen funktioniert.

+1

Danke. Es stellte sich heraus, dass unser Software-Hersteller einen Trigger für eine benutzerdefinierte Funktionalität ausprobierte und mir nicht bewusst war, dass er es in unsere _test DB geschafft hatte. (mein Kollege war sich dessen bewusst, aber er dachte nie, dass es ein Fehler war) – EkeshOkor