Операторы DDL с переменными для имен таблиц и столбцов - PullRequest
2 голосов
/ 16 августа 2010

В моей хранимой процедуре я создаю temp_tbl и хочу добавить несколько столбцов в курсоре или цикле while. Все отлично работает с курсором (создание temp_bl, но я не могу добавить столбец, когда строка столбца находится в переменной varchar.

WHILE @@FETCH_STATUS = 0
BEGIN       
SET @webadressenrow = 'Webadresse_'+CAST(@counter as nchar(10))

    ALTER TABLE IVS.tmpBus
        ADD @webadressenrow varchar(500) Null

    fetch next from cur_web into @webadressen
    SET @counter = @counter + 1
END

Приведенный выше код приводит к синтаксической ошибке, в то время как этот код работает:

WHILE @@FETCH_STATUS = 0
BEGIN       
SET @webadressenrow = 'Webadresse_'+CAST(@counter as nchar(10))

    ALTER TABLE IVS.tmpBus
     ADD SOMECOLUMNAME varchar(500) Null

    fetch next from cur_web into @webadressen
    SET @counter = @counter + 1
END

Кто-нибудь может дать мне подсказку по синтаксису этой маленькой проблемы?

Ответы [ 3 ]

2 голосов
/ 16 августа 2010

Вы не сможете параметризовать оператор ALTER TABLE, но вы можете создать SQL и выполнить его примерно так:

declare @sql nvarchar(max)
set @sql = 'create table IVS.tmpBus ( '

select
    @sql = @sql + 'Webadresse_' +
        row_number() over ( order by col ) +
        ' varchar(500) null, '
from sourceData

set @sql = substring(@sql, 1, len(@sql) - 2) + ' )'
exec @sql

Будьте осторожны с атаками безопасности / SQL-инъекций.

0 голосов
/ 18 августа 2010

Я решил проблему неоптимальным способом.Кодекс работает идеально для меня.Я надеюсь, что другой разочарованный программист может использовать это.

DECLARE cur_web CURSOR FOR
SELECT IVS.LG_Webadressen.Adresse FROM IVS.LG_Webadressen WHERE IVS.LG_Webadressen.FK_GID = @welche 

open cur_web /*Cursor wird geöffnet*/
fetch next from cur_web into @webadressen /*Erster Datensatz wird geholt*/

WHILE @@FETCH_STATUS = 0 /*Solange eine Datensatz vorhanden ist*/
BEGIN    
/*Spalte Adden*/
SET @webadressenrow = 'Webadresse_'+CAST(@counter as nchar(1)) /*Anhängen des     Durchlaufes an den Spaltennamen*/ 
SET @sql = 'ALTER TABLE IVS.temp_tbl ADD ' + @webadressenrow + ' VARCHAR(100)' /*Spalte adden*/
EXEC (@sql)    
/*Wert für die Webadresse wird reingeschrieben*/
SET @sql = 'UPDATE IVS.temp_tbl Set ' + @webadressenrow + ' = ''' + @webadressen + ''' WHERE GID = ' + CAST(@welche as nchar(10)) + ''
EXEC(@sql)
/*nächtser Datensatz wird geholt*/
fetch next from cur_web into @webadressen 
SET @counter = @counter + 1
END
/*Cursor zerstören und Schließen*/
CLOSE cur_web
DEALLOCATE cur_web
0 голосов
/ 16 августа 2010

В общем случае DDL операторы, то есть те, которые определяют таблицы и столбцы, не принимают переменные для имен таблиц или столбцов.

Иногда это можно обойти, подготовив операторы, но поддержка подготовленных DDL предоставляется не всеми механизмами баз данных.

Следующий пример работает в SQL Server 2005, хотя я хотел бы предположить, что динамическое добавление столбцов может быть не оптимальным решением

DECLARE @colname1 VARCHAR(10)
DECLARE @colname2 VARCHAR(10)
DECLARE @sql VARCHAR(MAX)

SET @colname1 = 'col1'
SET @colname2 = 'col2'

SET @sql = 'CREATE TABLE temptab (' + @colname1 + ' VARCHAR(10) )'

EXEC (@sql)

INSERT INTO temptab VALUES ('COl 1')


SET @sql = 'ALTER TABLE temptab ADD ' + @colname2 + ' VARCHAR(10)'

EXEC (@sql)

INSERT INTO temptab VALUES ('Col1', 'Col2')

SELECT * FROM temptab

DROP TABLE temptab

Дали следующие результаты

col1       col2
---------- ----------
COl 1      NULL
Col1       Col2
...