몇 년 동안 질문에 늦었지만, 빠르고 더러운 코드 생성을 위해서는 이와 같은 것이 필요했습니다. 다른 사람들이 언급했듯이 임시 테이블을 미리 정의하는 것이 더 쉽지만이 방법은 간단한 저장 프로 시저 쿼리 또는 SQL 문에 작동해야합니다.
이것은 약간 복잡하지만 DBA Stack Exchange의 Paul White 솔루션뿐만 아니라 여기에 기고자로부터 빌려옵니다. 저장 프로 시저 결과 열 유형 가져 오기 . 다시 한번,이 접근법을 반복하는 것은 다중 사용자 환경에서의 프로세스를 위해 설계된 것이 아닙니다. 이 경우 테이블 생성은 코드 생성 템플릿 프로세스에서 참조 할 수 있도록 전역 임시 테이블에서 짧은 시간 동안 설정됩니다.
필자는 이것을 완전히 테스트하지 않았으므로 경고가있을 수 있으므로 Paul White의 답변에서 MSDN 링크로 이동하십시오. 이는 SQL 2012 이상에 적용됩니다.
먼저 Oracle의 describe와 유사한 저장 프로 시저 sp_describe_first_result_set 을 사용하십시오 .
이것은 첫 번째 결과 세트의 첫 번째 행을 평가하므로 스토어드 프로 시저 또는 명령문이 여러 쿼리를 리턴하는 경우 첫 번째 결과 만 설명합니다.
임시 테이블 정의를 만들기 위해 선택할 단일 필드를 반환하는 작업을 분류하기 위해 저장 프로 시저를 만들었습니다.
CREATE OR ALTER PROCEDURE [dbo].[sp_GetTableDefinitionFromSqlBatch_DescribeFirstResultSet]
(
@sql NVARCHAR(4000)
,@table_name VARCHAR(100)
,@TableDefinition NVARCHAR(MAX) OUTPUT
)
AS
BEGIN
SET NOCOUNT ON
DECLARE @TempTableDefinition NVARCHAR(MAX)
DECLARE @NewLine NVARCHAR(4) = CHAR(13)+CHAR(10)
DECLARE @ResultDefinition TABLE ( --The View Definition per MSDN
is_hidden bit NOT NULL
, column_ordinal int NOT NULL
, [name] sysname NULL
, is_nullable bit NOT NULL
, system_type_id int NOT NULL
, system_type_name nvarchar(256) NULL
, max_length smallint NOT NULL
, [precision] tinyint NOT NULL
, scale tinyint NOT NULL
, collation_name sysname NULL
, user_type_id int NULL
, user_type_database sysname NULL
, user_type_schema sysname NULL
, user_type_name sysname NULL
, assembly_qualified_type_name nvarchar(4000)
, xml_collection_id int NULL
, xml_collection_database sysname NULL
, xml_collection_schema sysname NULL
, xml_collection_name sysname NULL
, is_xml_document bit NOT NULL
, is_case_sensitive bit NOT NULL
, is_fixed_length_clr_type bit NOT NULL
, source_server sysname NULL
, source_database sysname NULL
, source_schema sysname NULL
, source_table sysname NULL
, source_column sysname NULL
, is_identity_column bit NULL
, is_part_of_unique_key bit NULL
, is_updateable bit NULL
, is_computed_column bit NULL
, is_sparse_column_set bit NULL
, ordinal_in_order_by_list smallint NULL
, order_by_is_descending smallint NULL
, order_by_list_length smallint NULL
, tds_type_id int NOT NULL
, tds_length int NOT NULL
, tds_collation_id int NULL
, tds_collation_sort_id tinyint NULL
)
--Insert the description into table variable
INSERT @ResultDefinition
EXEC sp_describe_first_result_set @sql
--Now Build the string to create the table via union select statement
;WITH STMT AS (
SELECT N'CREATE TABLE ' + @table_name + N' (' AS TextVal
UNION ALL
SELECT
CONCAT(
CASE column_ordinal
WHEN 1 THEN ' ' ELSE ' , ' END --Determines if comma should precede
, QUOTENAME([name]) , ' ', system_type_name -- Column Name and SQL TYPE
,CASE is_nullable
WHEN 0 THEN ' NOT NULL' ELSE ' NULL' END --NULLABLE CONSTRAINT
) AS TextVal
FROM @ResultDefinition WHERE is_hidden = 0 -- May not be needed
UNION ALL
SELECT N');' + @NewLine
)
--Now Combine the rows to a single String
SELECT @TempTableDefinition = COALESCE (@TempTableDefinition + @NewLine + TextVal, TextVal) FROM STMT
SELECT @TableDefinition = @TempTableDefinition
END
수수께끼는 전역 테이블을 사용해야하지만 충돌에 대해 걱정하지 않고 자주 테이블에서 삭제하고 만들 수 있도록 고유하게 만들어야합니다.
이 예에서는 하이픈을 밑줄로 바꾸는 전역 변수에 Guid (FE264BF5_9C32_438F_8462_8A5DC8DEE49E)를 사용했습니다.
DECLARE @sql NVARCHAR(4000) = N'SELECT @@SERVERNAME as ServerName, GETDATE() AS Today;'
DECLARE @GlobalTempTable VARCHAR(100) = N'##FE264BF5_9C32_438F_8462_8A5DC8DEE49E_MyTempTable'
--@sql can be a stored procedure name like dbo.foo without parameters
DECLARE @TableDef NVARCHAR(MAX)
DROP TABLE IF EXISTS #MyTempTable
DROP TABLE IF EXISTS ##FE264BF5_9C32_438F_8462_8A5DC8DEE49E_MyTempTable
EXEC [dbo].[sp_GetTableDefinitionFromSqlBatch_DescribeFirstResultSet]
@sql, @GlobalTempTable, @TableDef OUTPUT
--Creates the global table ##FE264BF5_9C32_438F_8462_8A5DC8DEE49E_MyTempTable
EXEC sp_executesql @TableDef
--Now Call the stored procedure, SQL Statement with Params etc.
INSERT ##FE264BF5_9C32_438F_8462_8A5DC8DEE49E_MyTempTable
EXEC sp_executesql @sql
--Select the results into your undefined Temp Table from the Global Table
SELECT *
INTO #MyTempTable
FROM ##FE264BF5_9C32_438F_8462_8A5DC8DEE49E_MyTempTable
SELECT * FROM #MyTempTable
DROP TABLE IF EXISTS #MyTempTable
DROP TABLE IF EXISTS ##FE264BF5_9C32_438F_8462_8A5DC8DEE49E_MyTempTable
다시 말하지만, 간단한 저장 프로 시저 쿼리와 간단한 쿼리로 테스트했기 때문에 마일리지가 다를 수 있습니다. 이것이 누군가를 돕기를 바랍니다.