Создание и выбор табличных переменных динамически в хранимой процедуре SQL Server? - PullRequest
2 голосов
/ 04 сентября 2011

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

DECLARE @people TABLE 
( 
    id INT, 
    name VARCHAR(32) 
);

Как я буду создавать, если не знаете столбцы и типы данных. Сценарий: я должен создать переменную таблицы в соответствии с физическими таблицами и выбрать данные в них, использовать их в SP, а затем вернуть данные в переменных таблицы в программу на C #.

Например, у меня есть таблица сотрудников. Я хочу создать табличную переменную с той же структурой, что и у Employyes. Но упоминание столбцов занимает много времени (поскольку у сотрудников около 100 столбцов)

Пожалуйста, совет.

Ответы [ 2 ]

5 голосов
/ 04 сентября 2011

Итак, вот как вы можете динамически построить оператор 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 в запрос окно, и он выдаст вам хороший список имен столбцов через запятую, верно?

1 голос
/ 04 сентября 2011

Вы можете запросить системные таблицы, чтобы найти имена и типы столбцов, из которых состоит таблица.См. Этот вопрос и его ответы.

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

Это не поможет на стороне клиента.однако, поскольку он должен будет знать о типах и значениях возвращаемых данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...