TSQL выбирает таблицу Temp из динамического sql
Это кажется относительно простым, но, по-видимому, это не так.
Мне нужно создать временную таблицу на основе существующей таблицы с помощью синтаксиса select:
SELECT * INTO #TEMPTABLE FROM EXISTING_TABLE
Проблема заключается в том, что существующее имя таблицы принимается с помощью параметра...
Я могу получить данные таблицы через:
execute ('SELECT * FROM ' + @tableName)
но как я могу жениться на двух, чтобы я мог выполнить результаты из выполнения непосредственно в таблицу temp.
Столбцы для каждой таблицы, которые будут использоваться для этого, не являются одинаковыми, поэтому создание таблицы temp до получения данных нецелесообразно.
Я открыт для любых предложений, кроме использования глобальной таблицы temp.
Update:
Это совершенно смешно, но мои оговорки в глобальной таблице temp состоят в том, что это многопользовательская платформа поддается решению, если таблица будет задерживаться в течение длительного периода времени...
Sooo.. просто чтобы пройти мимо этой части, которую я начал с помощью execute для создания глобальной таблицы temp.
execute('select * into ##globalDynamicFormTable from ' + @tsFormTable)
Затем я использую глобальную таблицу temp для загрузки локальной таблицы temp:
select * into #tempTable from ##globalDynamicFormTable
Затем я отбрасываю глобальную таблицу.
drop table ##globalDynamicFormTable
Это грязно, и мне это не нравится, но пока пока я не получу лучшее решение, его придется работать.
В конце:
Я думаю, что нет способа обойти это.
Лучшим ответом также является:
Создайте представление в команде выполнения и используйте это для загрузки локальной таблицы temp в хранимой процедуре.
Создайте глобальную временную таблицу в команде выполнения и используйте ее для загрузки локальной таблицы temp.
С учетом сказанного я, вероятно, просто придерживаюсь глобальной таблицы temp, потому что создание и удаление представлений проверяется в моей организации, и я уверен, что они будут подвергать сомнению, что если это начнется все время.
Спасибо!
Ответы
Ответ 1
Рабочий пример.
DECLARE @TableName AS VARCHAR(100)
SELECT @TableName = 'YourTableName'
EXECUTE ('SELECT * INTO #TEMP FROM ' + @TableName +'; SELECT * FROM #TEMP;')
Второе решение с доступной временной таблицей
DECLARE @TableName AS VARCHAR(100)
SELECT @TableName = 'YOUR_TABLE_NAME'
EXECUTE ('CREATE VIEW vTemp AS
SELECT *
FROM ' + @TableName)
SELECT * INTO #TEMP FROM vTemp
--DROP THE VIEW HERE
DROP VIEW vTemp
/*START USING TEMP TABLE
************************/
--EX:
SELECT * FROM #TEMP
--DROP YOUR TEMP TABLE HERE
DROP TABLE #TEMP
Ответ 2
declare @sql varchar(100);
declare @tablename as varchar(100);
select @tablename = 'your_table_name';
create table #tmp
(col1 int, col2 int, col3 int);
set @sql = 'select aa, bb, cc from ' + @tablename;
insert into #tmp(col1, col2, col3) exec @sql;
select * from #tmp;
Ответ 3
Взгляните на OPENROWSET
и сделайте что-нибудь вроде:
SELECT * INTO #TEMPTABLE FROM OPENROWSET('SQLNCLI'
, 'Server=(local)\SQL2008;Trusted_Connection=yes;',
'SELECT * FROM ' + @tableName)
Ответ 4
Как я это сделал с точкой в динамическом sql (ранее был создан #AccPurch)
DECLARE @sql AS nvarchar(MAX)
declare @Month Nvarchar(1000)
--DROP TABLE #temp
select distinct YYYYMM into #temp from #AccPurch AS ap
SELECT @Month = COALESCE(@Month, '') + '[' + CAST(YYYYMM AS VarChar(8)) + '],' FROM #temp
SELECT @Month= LEFT(@Month,len(@Month)-1)
SET @sql = N'SELECT UserID, '+ @Month + N' into ##final_Donovan_12345 FROM (
Select ap.AccPurch ,
ap.YYYYMM ,
ap.UserID ,
ap.AccountNumber
FROM #AccPurch AS ap
) p
Pivot (SUM(AccPurch) FOR YYYYMM IN ('[email protected]+ N')) as pvt'
EXEC sp_executesql @sql
Select * INTO #final From ##final_Donovan_12345
DROP TABLE ##final_Donovan_12345
Select * From #final AS f
Ответ 5
Я могу думать о нескольких способах выбора данных из таблицы, имя которой было сгенерировано динамически, без использования глобальных временных таблиц.
Решение 1
Создайте строку, содержащую имя исходной таблицы, и сделайте весь ваш запрос динамическим.
Решение 2
Это решение, включающее переменную таблицы, будет работать, если вы знаете...
в исходной таблице.
-- Number of rows in your source table
DECLARE @RowCount INT;
SELECT @RowCount = SUM(st.row_count) FROM sys.dm_db_partition_stats st WHERE object_name(object_id) = EmployeesWeek_ + CONVERT( VARCHAR(10),WEEK(GETDATE()) ) AND (index_id < 2);
-- All columns from your source table
DECLARE @col1 int;
DECLARE @col2 varchar(50);
DECLARE @col3 varchar(5);
DECLARE @col4 int;
DECLARE @col5 smalldatetime;
DECLARE @col6 bit;
-- This table variable will store the data
DECLARE @Dump TABLE (
col1 int,
col2 varchar(50),
col3 varchar(5),
col4 int,
col5 smalldatetime,
col6 bit
)
DECLARE @RowIter INT = 1;
WHILE @RowIter <= @RowCount
BEGIN
DECLARE @QueryString NVARCHAR(MAX) = CONCAT(N'
SELECT
@col1 = ID,
@col2 = Name,
@col3 = NameAbbr,
@col4 = UpdatedBy,
@col5 = DateUpdated,
@col6 = Active
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY PKArea ASC) AS RowNum,
*
FROM
EmployeesWeek_',WEEK(GETDATE()),'
) sq
WHERE
RowNum = ', @RowIter , '
;
');
EXEC dbo.sp_executesql
@QueryString,
-- OUTPUT VARIABLE DECLARATION
N'
@col1 int out,
@col2 varchar(50) out,
@col3 varchar(5) out,
@col4 int out,
@col5 smalldatetime out,
@col6 bit out
',
-- ALL OUTPUT VARIABLES
@col1 out,
@col2 out,
@col3 out,
@col4 out,
@col5 out,
@col6 out
;
INSERT INTO @Dump values(@col1, @col2, @col3, @col4, @col5, @col6);
SET @RowIter = @RowIter + 1;
END
SELECT * FROM @Dump;
Моя интуиция заявляет, что на больших наборах данных это медленно замедляется, и я не знаю, можно ли сделать этот запрос динамическим (это должно быть возможным, запросив список имен столбцов, используя грязные хаки для создания строки, содержащей список столбцов и т.д., но пока я не могу больше тратить на это...), позволяя вам выбирать данные из таблицы с любым количеством столбцов; но опять же, это SQL...