2016-02-19 57 views
2

我正在嘗試在T-SQL中創建一個包裝程序,我不確定數據類型是什麼。我可以在沒有INSERT INTO語句的情況下運行wrapper,並且我得到的數據很好,但我需要將它放在一個表中。創建具有未知數據類型的包裝

每當我使用INSERT INTO我得到一個錯誤:

Column name or number of supplied values does not match table definition

我解析回到我的代碼並不能看到任何列名不匹配,所以我在想,它必須是一種數據類型。我已經瀏覽了我正在封裝的過程,看看我是否可以找到數據類型,但有些不在那裏定義;我參考了他們從中抽取一些數據來查找定義的表格;我已對所有數據運行SQL_VARIANT_PROPERTY以查看它的數據類型(儘管其中一些數據爲空)。

有沒有更好的方法讓我找出錯誤的確切位置?

+0

請提供實際的代碼。 – dfundako

+0

「包裝」是「INSERT ... EXEC」? –

+0

我可以發佈包裝代碼,但我不確定沒有我包裝的3000行代碼會有幫助。下面我找到了一個解決方法來回答我自己的問題,但爲了澄清,我的「包裝器」包括聲明過程中的所有參數與包裝過程相同,然後使用EXEC執行該過程,然後是相同的參數列表。在這兩者之間是一個「DECLARE @ReportSet TABLE」,包含我期望從包裝過程中獲得的所有字段和數據類型,以及「INSERT INTO @ReportSet」。 – DaveX

回答

0

我想你可以使用sp_describe_first_result_set(可從SQL2012)和FMTONLY找到你的存儲過程結果模式。像這樣的東西:

EXEC sp_describe_first_result_set 
    @tsql = N'SET FMTONLY OFF; EXEC yourProcedure <params are embedded here>' 

更多細節可以發現here。但是,如果我沒有記錯的話,只有當你的程序使用了確定性模式(沒有SELECT INTO #tempTable或類似的東西)時,它才起作用。

找出結果模式的一個訣竅就是將結果實際地物化爲臨時創建的表格。但是,這並不容易,因爲SELECT INTO不適用於EXEC procedure。一個解決方法是:

1)定義一個鏈接服務器到實例本身。例如。環回

2)執行你的程序是這樣的(對於SQL 2008R2):

SELECT * INTO tempTableToHoldDataAndStructure 
    FROM OPENQUERY(' + @LoopBackServerName + ', ''set fmtonly off exec ' + @ProcedureFullName + ' ' + @ParamsStr 

其中

@LoopBackServerName = 'loopback' 
@ProcedureFullName = loopback.database.schema.procedure_name 
@ParamsStr = embedded parameters 

對於SQL2012我覺得如果不提供結果集的執行可能會失敗(即模式定義的預期結果,這在這種情況下是種雞蛋問題):

' WITH RESULT SETS ((' + @ResultSetStr + '))''); 
+0

感謝您的回覆。當我對T-SQL更熟悉時,我確信我會回來嘗試一下,但現在它已經有點過頭了。我發現了一個低技術,緩慢的解決方案 - 在下面發佈。 – DaveX

+0

我嘗試了你的第一個建議。我沒有寫下我正在包裝的程序,這絕對是我的頭腦。這是我得到的錯誤消息: 「消息11514,級別16,狀態1,過程sp_describe_first_result_set,1號線 元數據不能確定,因爲聲明 'EXEC * EXTGEN_SpName * CONTEXTNAME ,*用戶名 ,*的SessionID輸出'在過程'InitSessionContextWithUserSp'中包含動態SQL,請考慮使用WITH RESULT SETS子句明確描述結果集。「 這些「*」字符確實是「@」,但它不會讓我這樣發佈。 – DaveX

0

好的,我有解決我的問題。這是乏味的,但我可以做的乏味。隨機猜測是讓我瘋狂的原因。我正在打包的過程轉儲51列。我已經知道我可以在不把任何東西放到桌子上的情況下工作。所以我決定在我打包的過程中註釋掉select語句的一部分,所以只能選擇1列。 (首先我製作了一個該程序的副本,所以我沒有搞錯原來的內容;然後我從包裝中引用了該副本)。保存了兩個,運行它,它工作。到現在爲止還挺好。我可以一行一行地完成它,但我更像是一個二元類型的傢伙,所以我走了一半 - 現在我在包括select語句和我的表格中包括大約25列 - 並且它仍然加工。重複這個程序,直到它不再起作用,然後回溯直到它再次出現。我的錯誤是識別其中一個數據類型,後面跟着「IDENTITY」。我不確定當我離開時會發生什麼,但至少我的包裝工作。