2012-07-11 22 views
5

Ich habe gerade festgestellt, dass ich die falschen Daten für eine Spalte in meiner Tabelle erfasst habe. Ich habe das Problem behoben, aber die Daten, die ich bisher erfasst habe, bleiben falsch.Wie man Spalten Daten mit anderen Tabellen Daten aktualisieren TSQL

Lassen Sie uns den Namen meiner Tabellen TableIWantToCorrect und TableWithIDs

In TableIWantToCorrect, ich habe einen Fremdschlüssel zu TableWithIDs. Das ist was falsch ist.

Ich bin in der Lage, die Daten zu korrigieren, indem Teilstring einer Spalte in TableIWantToCorrect mit einer Spalte in TableWithIDs verglichen wird.

Also zur Zeit, ich habe

TableIWantToCorrect

Name   ForeignKey 
123-abc-123  15 
456-def-456  15 
789-ghi-789  15 

TableWithIDs

CompareName id 
abc   1 
def   2 
ghi   3 

Deshalb mag ich TableIWantToCorrect aktualisieren, um den richtigen ForeignKey Wert zu haben, wenn der Teil in der Name entspricht der Teilzeichenfolge im Vergleich Name. Die Position des Teilstrings ist immer gleich, so dass ich die Methode Substring verwenden kann.

Mein Versuch:

Update TableIWantToCorrect 
SET ForeignKey = 
     (SELECT id 
     FROM TableWithIDs 
     WHERE UPPER(CompareName) = UPPER((SUBSTRING(TableIWantToCorrect.Name, 4, 3))) 

Das Ergebnis:

Unterabfrage gab mehr als 1 Wert. Dies ist nicht erlaubt, wenn die Unterabfrage folgt =,! =, <, < =,>,> = oder wenn die Unterabfrage als ein Ausdruck verwendet wird. Die Anweisung wurde beendet.

Ich weiß, ich habe etwas Dummes getan. Was habe ich hier falsch gemacht?

+1

Ihre Inline-Abfrage ist mehr als eine Zeile zurückgibt daher das Problem. Führen Sie diese Abfrage, um herauszufinden, welche davon wiederholen SELECT CompareName, COUNT (1) \t VON TableWithIDs GROUP BY CompareName MIT COUNT (1)> 1 \t ' – Chandu

+0

Haben Sie noch den Fehler erhalten, wenn Sie die Unterabfrage zu ändern benutze 'SELECT DISTINCT id'? Wenn dies der Fall ist, gibt es mehrere mögliche Übereinstimmungen und es ist mehrdeutig, welche zu verwenden ist. –

+0

mögliches Duplikat von [UPDATE von SELECT mit SQL Server] (http://stackoverflow.com/questions/2334712/update-from-select-using-sql-server) –

Antwort

13

Der Fehler ist, weil die Unterabfrage für die UPDATE mehr als einen Datensatz zurück. Um dies zu beheben, können Sie dies ein JOIN mit Verwendung tun UPDATE

UPDATE t1 
SET ForeignKey = t2.id 
FROM TableIWantToCorrect t1 
INNER JOIN TableWithIDs t2 
    ON UPPER(t2.CompareName) = UPPER(SUBSTRING(t1.Name, 4, 3)) 
+1

Ich weiß, dass dies speziell eine SQL Server-Frage ist, aber wenn Sie MySQL-Entsprechungen dafür haben möchten, versuchen Sie es hier: http://Stackoverflow.com/a/11709090/403264 – JonRed

2
Update TableIWantToCorrect 
SET ForeignKey = s.id 
FROM TableIWantToCorrect , TableWithIDs as s 
WHERE UPPER(s.CompareName) = UPPER((SUBSTRING(TableIWantToCorrect.Name, 4, 3)) 
+1

Sie können immer sagen, wer in Oracle arbeitet, sie verwenden nie der Join-Befehl ;) – Limey

+1

Leider schwinge ich zwischen Oracle und Sql Server, also werde ich irgendwann verwirrt ...!trotzdem ergeben sie das selbe ergebnis aber immernoch sollte beitreten sollte bevorzugt werden. http://stackoverflow.com/questions/1018822/inner-join-on-vs-where-clause – praveen

+1

Ich war 10 Jahre in Oracle, und ich hasste die Aussage beitreten! Aus irgendeinem Grund fand ich es immer schwer zu lesen, aber nach Jahren im SQL-Server habe ich die Fehler meiner Wege gesehen und verwende immer Joins. – Limey

-1
--CREATE FUNCTION dbo.ufn_FindReports 
--(@InEmpID INTEGER) 
--RETURNS @retFindReports TABLE 
--(
-- EmployeeID int primary key NOT NULL, 
-- FirstName nvarchar(255) NOT NULL, 
-- LastName nvarchar(255) NOT NULL, 
-- JobTitle nvarchar(50) NOT NULL 

--) 
----Returns a result set that lists all the employees who report to the 
----specific employee directly or indirectly.*/ 
--AS 
--BEGIN 
--WITH EMP_cte(EmployeeID, OrganizationNode, FirstName, LastName, JobTitle, RecursionLevel) -- CTE name and columns 
-- AS (
--  SELECT e.EmployeeID, e.ManagerID, p.FirstName, p.LastName, P.JobTitle, 0 -- Get the initial list of Employees for Manager n 
--  FROM HumanResources.Employee e 
--INNER JOIN Person.Person p 
--ON p.Employeeid = e.EmployeeID 
--  WHERE e.EmployeeID = @InEmpID 
--  UNION ALL 
--  SELECT e.EmployeeID, e.ManagerID, p.FirstName, p.LastName, P.JobTitle, RecursionLevel + 1 -- Join recursive member to anchor 
--  FROM HumanResources.Employee e 
--   INNER JOIN EMP_cte 
--   ON e.ORGANIZATIONNODE.GetAncestor(1) = EMP_cte.OrganizationNode 
--INNER JOIN Person.Person p 
--ON p.Employeeid= e.EmployeeID 
--  ) 
---- copy the required columns to the result of the function 
-- INSERT @retFindReports 
-- SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel 
-- FROM EMP_cte 
-- RETURN 
--END; 
--GO 

> 
Verwandte Themen