2012-07-11 11 views
5

Acabo de darme cuenta de que he estado capturando los datos incorrectos para una columna en mi tabla. He resuelto el problema, sin embargo, los datos que he capturado hasta ahora siguen siendo incorrectos. NombreCómo actualizar datos de una columna usando otra tabla de datos TSQL

de dejar que mis tablas TableIWantToCorrect y TableWithIDs

En TableIWantToCorrect, tengo una clave externa a TableWithIDs. Esto es lo que es incorrecto

Puedo corregir los datos comparando la subcadena de una columna en TableIWantToCorrect con una columna en TableWithIDs.

Así Actualmente, tengo

TableIWantToCorrect

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

TableWithIDs

CompareName id 
abc   1 
def   2 
ghi   3 

Así que quieren actualizar TableIWantToCorrect tener el valor ForeignKey correcta cuando la subcadena en el El nombre es igual a la subcadena en Comparar nombre. La posición de la subcadena es siempre la misma, así que puedo usar el método Substring.

Mi intento:

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

El resultado:

subconsulta devuelve más de 1 valor. Esto no está permitido cuando la subconsulta sigue =,! =, <, < =,>,> = o cuando la subconsulta se usa como una expresión. La instrucción se ha terminado.

Sé que he hecho algo tonto. ¿Qué he hecho incorrectamente aquí?

+1

Su línea-consulta está volviendo más que una fila de ahí el tema. Ejecutar esta consulta para averiguar cuáles están repitiendo SELECT CompareName, COUNT (1) \t DE TableWithIDs GROUP BY CompareName TIENE CUENTA (1)> 1 \t ' – Chandu

+0

¿Todavía consigo el error si cambia la subconsulta para usar 'SELECT DISTINCT id'? Si es así, hay múltiples coincidencias posibles y es ambiguo cuál usar. –

+0

posible duplicado de [ACTUALIZACIÓN de SELECT usando SQL Server] (http://stackoverflow.com/questions/2334712/update-from-select-using-sql-server) –

Respuesta

13

El error es debido a que su subconsulta devuelve más de un registro para el UPDATE. Para solucionar esto, se puede hacer esto utilizando una JOIN con su 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

Sé que esto es específicamente una pregunta del Servidor SQL, pero si quiere los equivalentes de MySQL para hacerlo, intente aquí: 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

Siempre se puede saber quién trabaja en Oracle, nunca lo usan el comando de unión ;) – Limey

+1

Desafortunadamente me muevo entre el servidor Oracle y Sql así que me confundo un poco ..!sin embargo, arrojan el mismo resultado, pero aún así se deben unir .http: //stackoverflow.com/questions/1018822/inner-join-on-vs-where-clause – praveen

+1

Tenía 10 años en Oracle, y solía odiar el ¡Únete a la declaración! Por alguna razón, siempre me pareció difícil de leer, pero después de años en el servidor SQL, he visto los errores de mis formas y siempre uso las uniones. – 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 

> 
Cuestiones relacionadas