2012-12-14 11 views
5

Ho questo tavolo in questo momentoCome aggiornare una colonna tramite Row_Number con un valore diverso per ogni riga?

CREATE TABLE [dbo].[DatosLegales](
    [IdCliente] [int] NOT NULL, 
    [IdDatoLegal] [int] NULL, 
    [Nombre] [varchar](max) NULL, 
    [RFC] [varchar](13) NULL, 
    [CURP] [varchar](20) NULL, 
    [IMSS] [varchar](20) NULL, 
    [Calle] [varchar](100) NULL, 
    [Numero] [varchar](10) NULL, 
    [Colonia] [varchar](100) NULL, 
    [Pais] [varchar](50) NULL, 
    [Estado] [varchar](50) NULL, 
    [Ciudad] [varchar](50) NULL, 
    [CodigoPostal] [varchar](10) NULL, 
    [Telefono] [varchar](13) NULL, 
    [TipoEmpresa] [varchar](20) NULL, 
    [Tipo] [varchar](20) NULL, 
CONSTRAINT [PK_DatosLegales] PRIMARY KEY CLUSTERED 
(
    [IdCliente] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) 

ho bisogno di aggiornare la colonna IdDatoLegal. In questo momento ho 80 righe su quel tavolo, quindi ho bisogno di aggiornare ogni riga con i numeri 1, 2, 3 ... 79, 80.

Ho provato semplici query alle stored procedure senza alcun esito.

ho questo procedimento negozi in questo momento:

ALTER PROCEDURE dbo.ActualizarDatosLegales 
@RowCount int 
AS 
DECLARE @Inicio int 
SET @Inicio = 0 
WHILE @Inicio < @@RowCount 
SET @Inicio += 1; 
BEGIN 
UPDATE DatosLegales SET IdDatoLegal = @Inicio WHERE (SELECT ROW_NUMBER() OVER (ORDER BY IdCliente) AS RowNum FROM DatosLegales) = @Inicio; 
END 

Si restituisce questo messaggio quando l'eseguo

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. 

immagino che sia perché nella sottoquery (SELECT ROW_NUMBER() OVER (ORDER BY IdCliente) AS RowNum FROM DatosLegales) restituisce 80 righe in cui dovrebbe restituire solo una (ma ogni volta dovrebbe essere un numero diverso.

Sai cosa devo aggiungere a la sottoquery per farlo funzionare? e soprattutto, il ciclo e il resto della procedura sono giusti?

grazie in anticipo

+0

stai usando SQL Server? – luchosrock

+0

@luchosrock: la sintassi, i delimitatori di parentesi quadre e il messaggio di errore indicano SQL Server (anche se probabilmente Sybase se ha gli stessi messaggi di errore, suppongo). –

risposta

18

È possibile aggiornare tutte le righe in un unico prospetto utilizzando un CTE, come di seguito.

;WITH T 
    AS (SELECT IdDatoLegal, 
       Row_number() OVER (ORDER BY IdCliente) AS RN 
     FROM dbo.DatosLegales) 
UPDATE T 
SET IdDatoLegal = RN 
+0

Un po 'confuso: questo aggiornamento 'DatosLegales'? – Kaf

+1

Sì. Il CTE agisce come una vista aggiornabile e viene tradotto in un aggiornamento sulla colonna della tabella di base. –

+0

È bello sapere. Inoltre, questo aggiornamento dice, IdCliente = 56, IdDatoLegal = 56 (RN).? – Kaf

5
UPDATE D 
SET IdDatoLegal = RN 
FROM DatosLegales D JOIN 
(
    SELECT IdCliente, Row_number() OVER (ORDER BY IdCliente) AS RN 
    FROM DatosLegales 
) Temp 
ON D.IdCliente = Temp.IdCliente 
+0

Non è necessario un join back sul tavolo di base. Il piano per questo è meno efficiente in quanto aggiunge il join e uno spool. –

+0

Ah okay, ho appena fatto la domanda simile in un altro modo. La tua risposta mi ha confuso. – Kaf

Problemi correlati