2012-07-11 15 views
5

Ho appena realizzato di aver acquisito dati errati per una colonna nella mia tabella. Ho risolto il problema, tuttavia, i dati che ho catturato finora non sono corretti. NomeCome aggiornare i dati di una colonna utilizzando altri dati di tabelle TSQL

di lasciare che i miei tavoli TableIWantToCorrect e TableWithIDs

In TableIWantToCorrect, ho una chiave esterna per TableWithIDs. Questo è ciò che è sbagliato.

Sono in grado di correggere i dati confrontando la sottostringa di una colonna in TableIWantToCorrect con una colonna in TableWithIDs.

Così Attualmente, ho

TableIWantToCorrect

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

TableWithIDs

CompareName id 
abc   1 
def   2 
ghi   3 

quindi voglio aggiornare TableIWantToCorrect per avere il valore ForeignKey corretto quando la sotto stringa nella Il nome è uguale alla sottostringa in Confronta nome. La posizione della sottostringa è sempre la stessa, quindi è possibile utilizzare il metodo Substring.

Il mio tentativo:

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

Il risultato:

subquery ha restituito più 1 valore. Ciò non è consentito quando la sottoquery segue =,! =, <, < =,>,> = o quando la sottoquery viene utilizzata come un'espressione. La dichiarazione è stata chiusa.

So di aver fatto qualcosa di sciocco. Cosa ho fatto in modo errato qui?

+1

tuo inline-query sta tornando più di una riga da qui il problema. Eseguire questa query per capire quali stanno ripetendo 'SELEZIONA CompareName, COUNT (1) \t DA TableWithIDs GROUP BY CompareName HAVING COUNT (1)> 1 \t ' – Chandu

+0

Non è ancora ottenere l'errore se si modifica la sottoquery per usa 'SELECT DISTINCT id'? Se è così ci sono più possibili corrispondenze ed è ambiguo quale usare. –

+0

possibile duplicato di [UPDATE da SELECT usando SQL Server] (http://stackoverflow.com/questions/2334712/update-from-select-using-sql-server) –

risposta

13

L'errore è perché il vostro subquery sta tornando più di un record per il UPDATE. Per risolvere questo problema, è possibile farlo utilizzando un JOIN con il 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

So che si tratta in particolare di una domanda di SQL Server, ma se si vogliono gli equivalenti MySQL per farlo, provare qui: 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

Puoi sempre dire chi lavora in Oracle, non usano mai il comando join. ;) – Limey

+1

Sfortunatamente oscuro tra Oracle e il server Sql, quindi un po 'di tempo mi confondere ..!tuttavia producono lo stesso risultato, ma dovrebbero comunque essere preferiti. http://stackoverflow.com/questions/1018822/inner-join-on-vs-where-clause – praveen

+1

Avevo 10 anni in Oracle e odiavo il Iscriviti alla dichiarazione! Per qualche motivo, ho sempre trovato difficile leggere, ma dopo anni in SQL server, ho visto gli errori dei miei modi e ho sempre utilizzato i join. – 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 

> 
Problemi correlati