SQL Server 2005 e Identity Column

martedì 31 gennaio 2012 - 11.58
Tag Elenco Tags  SQL Server 2005  |  SQL Server 2000

luca1988 Profilo | Newbie

Ciao a tutti,

sto affrontando la migrazione di un applicativo da SQL Server 2000 a SQL Server 2005.

In entrambi gli ambienti ho una tabella (TB_REPORT_FLOW) che contiene, tra le altre, una colonna (ID_REPORT) in cui è specificata una IDENTITY con Start da 1 e Incremento a 1.

Ad un certo punto il motore dell'applicazione chimama una Stored Procedure che contiene il seguente codice:

EXEC('SELECT P.*, Identity(int,1,1) AS RowID INTO #TEMP FROM (' + @sql + ') As P SELECT ' + @sql_fields + ', @@ROWCOUNT AS COUNTER FROM #TEMP where RowId between ' + @row_start + ' and ' + @row_end + ' order by RowID DROP TABLE #TEMP')

Dove @sql è a sua volta una query. Questa query:

SELECT TOP 99.99 PERCENT ID_REPORT, SCHEDULE, DESTINATION, FLOW, JOB, SLA, DELTA_GG_SLA, CUTOFF, REAL_GENERATION_TIME, REAL_START_TIME, REAL_END_TIME, DELTA_GG_END_TIME, WARNING_END_TIME, CASE WHEN WARNING_END_TIME = 0 THEN 'COLORE_VERDE' WHEN WARNING_END_TIME = 1 THEN 'COLORE_ROSSO' END AS WARNING_END_TIME_CLASS, WARNING_GENERATION, CASE WHEN WARNING_GENERATION = 0 THEN 'COLORE_VERDE' WHEN WARNING_GENERATION = 1 THEN 'COLORE_ROSSO' END AS WARNING_GENERATION_CLASS, LAST_ACTION, CASE WHEN SUBSTRING(LAST_ACTION, 1, 10) = SUBSTRING((CONVERT(VARCHAR(23), GETDATE(), 121)), 1, 10) THEN 'UPDATED' ELSE 'NOT_UPDATED' END AS UPDATE_STATUS FROM dbo.TB_REPORT_FLOW.

Ora, in parole povere.. su SQL Server 2000 tutto funziona alla perfezione mentre su SQL Server 2005 mi restituisce l'errore:

Cannot add identity column, using the SELECT INTO statement, to table '#TEMP', which already has column 'ID_REPORT' that inherits the identity property.

Dato che il funzionamento della applicazione NON può essere in alcun modo modificato, il mio dubbio era il seguente: per caso su SQL Server 2005 esistono restrizioni in merito alle IDENTITY COLUMN che non erano presenti in SQL Server 2000? E' possibile agire con qualche "Workaround"?

Grazie mille a tutti,

Luca

alx_81 Profilo | Guru

>Ciao a tutti,
ciao

>Ad un certo punto il motore dell'applicazione chimama una Stored
>Procedure che contiene il seguente codice:
>
>EXEC('SELECT P.*, Identity(int,1,1) AS RowID INTO #TEMP FROM
>(' + @sql + ') As P SELECT ' + @sql_fields + ', @@ROWCOUNT AS
>COUNTER FROM #TEMP where RowId between ' + @row_start + ' and
>' + @row_end + ' order by RowID DROP TABLE #TEMP')
>Dove @sql è a sua volta una query. Questa query:
@sql non la usa mai nella riga precedente.. poi leggo un "INTO #TEMP, FROM #TEMP"..... sinceramente non capisco.
Puoi postare il codice della stored procedure? @sql non lo vedo mai..

>Cannot add identity column, using the SELECT INTO statement,
>to table '#TEMP', which already has column 'ID_REPORT' that inherits
>the identity property.
questo perchè sembra che #TEMP sia già stata costruita da qualche parte con un'identità.. ma non si capisce dal tuo post.

dovrai passare più dettagli credo
>Grazie mille a tutti,
di nulla!
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

luca1988 Profilo | Newbie

Ciao Alessandro e grazie mille per la risposta.

La Stored Procedure fa poco altro, oltre che accettare parametri ed eseguire il codice postato sopra. In ogni caso questa è la Stored:

USE [IlMioDatabase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[LaMiaProcedura]
@sql varchar(8000),
@sql_fields varchar(8000),
@row_start int,
@row_end int,
@result varchar(8000) output
AS
SET NOCOUNT ON
EXEC('SELECT P.*, Identity(int,1,1) AS RowID INTO #TEMP FROM (' + @sql + ') As P SELECT ' + @sql_fields + ', @@ROWCOUNT AS COUNTER FROM #TEMP where RowId between ' + @row_start + ' and ' + @row_end + ' order by RowID DROP TABLE #TEMP')

In pratica @sql è un parametro che viene passato alla Stored Procedure e contiene a sua volta una query (quella con il TOP 99.99 che ho postato nel messaggio precedente).

La SP, da quanto ho capito, non fa niente altro che eseguire tre query:

1) SELECT P.*, Identity(int,1,1) AS RowID INTO #TEMP FROM (' + @sql + ') As P
2) SELECT ' + @sql_fields + ', @@ROWCOUNT AS COUNTER FROM #TEMP where RowId between ' + @row_start + ' and ' + @row_end + ' order by RowID 3) DROP TABLE #TEMP

I parametri @row_start e @row_end non sono rilevanti; @sql_fields contiene un insieme di colonne da estrarre.

Il problema, da quanto ho capito, è che si cerca di inserire una identity (Identity) in una tabella temporanea (#TEMP) che viene popolata grazie ad una select che estrae i dati da una tabella reale in cui compare una colonna che è a sua volta una identity (ID_REPORT). Morale: risultano esserci due colonne con identity. Per quanto la cosa sembra essere strana, su SQL Server 2000 questo giro non crea problemi, mentre SQL Server 2005 restituisce l'errore postato nel primo messaggio.

Grazie mille a chiunque vorrà aiutarmi!

alx_81 Profilo | Guru

>1) SELECT P.*, Identity(int,1,1) AS RowID INTO #TEMP FROM ('
>+ @sql + ') As P
>2) SELECT ' + @sql_fields + ', @@ROWCOUNT AS COUNTER FROM #TEMP
>where RowId between ' + @row_start + ' and ' + @row_end + ' order
>by RowID 3) DROP TABLE #TEMP
sì, senza ; non avevo capito molto il giro. Ora ci siamo.

>Il problema, da quanto ho capito, è che si cerca di inserire
>una identity (Identity) in una tabella temporanea (#TEMP) che
>viene popolata grazie ad una select che estrae i dati da una
>tabella reale in cui compare una colonna che è a sua volta una
>identity (ID_REPORT). Morale: risultano esserci due colonne con
>identity. Per quanto la cosa sembra essere strana, su SQL Server
>2000 questo giro non crea problemi, mentre SQL Server 2005 restituisce
>l'errore postato nel primo messaggio.
su 2005 puoi impostare il compatibility level a livello di database. Prova a mettere 80 (2000) e riesegui i comandi. Controlla se funziona.
SQL Server comunque consente solo un'identity per tabella.. quindi non capisco perchè in 2000 non desse problemi. Se il problema è di doppia identity avresti dovuto prenderlo anche su 2000.
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

luca1988 Profilo | Newbie

Grazie mille Alessandro,

proverò e ti farò sapere.
Visto che sul DB non possiamo intervenire in quanto non è in gestione a noi stavo cercando di trovare altre strade, magari più "brutte" ma sicuramente funzionanti.. stavo pensando a questo:

La query "originale", quella @sql che viene passata come parametro alla SP, attualmente fa una SELECT su una TABELLA in cui è definita una Identity.

Se io modificassi questa SELECT e le facessi fare una estrazione da una VISTA invece che dalla TABELLA ORIGINALE? Questa VISTA sarebbe costruita come semplice SELECT sulla tabella incriminata. A quel punto, per quanto "brutto", questo dovrebbe risolvere il problema della doppia identity..

Riassumendo:

1) Tabella TB_REPORT_FLOW con parametro ID_REPORT (identity)
2) Vista VW_REPORT_FLOW che fa una SELECT sulla tabella del punto 1
3) Il parametro @sql diventa "SELECT tutti i parametri FROM VW_REPORT_FLOW"
4) La SP riceve il parametro @sql e dovrebbe riuscire ad eseguire il suo lavoro.

Corretto o mi sto perdendo qualcosa?

Grazie ancora,

Luca

alx_81 Profilo | Guru

>2) Vista VW_REPORT_FLOW che fa una SELECT sulla tabella del punto 1
>3) Il parametro @sql diventa "SELECT tutti i parametri FROM VW_REPORT_FLOW"
>Corretto o mi sto perdendo qualcosa?
attenzione perchè la select sulla vista proprio non deve contenere l'identità fra i campi, sennò hai il medesimo problema..
osserva questo esempio:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

>Grazie ancora,
di nulla!
se ritieni che ti abbia aiutato, accetta la risposta così chiudiamo il thread
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

luca1988 Profilo | Newbie

Grazie Alessandro,

appena ho un attimo di tempo proverò con la vista.
In ogni caso accetto la risposta.
Buona giornata,

Luca
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5