Итак, вот как вы можете динамически построить оператор DECLARE TABLE
:
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'';
SELECT @sql = @sql + ',
' + c.name + ' ' + t.name
+ CASE
WHEN t.name LIKE '%char' OR t.name LIKE '%binary' THEN
'(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE
CONVERT(VARCHAR(4), c.max_length/CASE WHEN t.name LIKE 'n%'
THEN 2 ELSE 1 END) END + ')'
WHEN t.name IN ('float') THEN
'(' + CONVERT(VARCHAR(4), c.precision) + ')'
WHEN t.name IN ('decimal', 'numeric') THEN
'(' + CONVERT(VARCHAR(4), c.precision) + ','
+ CONVERT(VARCHAR(4), c.scale) + ')'
ELSE ''
END
FROM sys.columns AS c
INNER JOIN sys.types AS t
ON c.system_type_id = t.system_type_id
AND c.user_type_id = t.user_type_id
WHERE c.[object_id] = OBJECT_ID('dbo.Employees')
ORDER BY c.column_id;
SET @sql = 'DECLARE @people TABLE (' + STUFF(@sql, 1, 1, '') + '
);';
SELECT @sql;
Но что теперь? Вы не можете вставить в него вне области динамического SQL:
EXEC sp_executesql @sql;
INSERT @people(id, name) SELECT 1,'foo';
выдает эту ошибку:
Msg 1087, Level 15, State 2, ...
Must declare the table variable "@people".
Еще раз: проблема с областью видимости - @people
существует только в динамическом SQL и перестает существовать, как только она завершается. Так что пока вы можете продолжить и добавить к переменной @sql
:
SET @sql = @sql + 'INSERT @people ...; SELECT id, name FROM @people;';
... это очень быстро выйдет из-под контроля. И я до сих пор не знаю, как ваш код C # может знать обо всех задействованных столбцах и типах данных, но для этого слишком сложно написать SQL ... вы знаете, что вы можете перетащить узел столбцов из Object Explorer в запрос окно, и он выдаст вам хороший список имен столбцов через запятую, верно?