我有一個用戶填寫的InfoPath表格。它獲得一個唯一的報告編號,並且在報告中他們可以選擇零個或多個受影響的部分,每個部分都有一堆列。受影響部件的列表可能隨着報告的處理而改變。向SharePoint提交或重新提交報表時,會調用SQL存儲過程,其參數包括列數據分號 - 用一個代表多行的NVARCHAR(MAX)
分隔。存儲過程分析以分號分隔的NVARCHAR
以填充表變量,然後將該表變量與將用於數據分析的主表合併。當用戶只有一個受影響的部件每個報告有給定的部件號時(因爲我的MERGE
語句使用它來確定它是否需要更新現有的行或創建一個新的行),並且最初這是一個可以接受的限制。粗糙SQL摘要:MERGE使用表格變量時沒有明顯的匹配條件
CREATE TABLE [Report_to_Parts](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Report_ID] [nvarchar](255) NOT NULL,
[PartNumberOrdered] [nvarchar](255) NULL,
[OtherColumns] [nvarchar](255) NULL)
CREATE PROCEDURE [MergeReport_sp]
@paramReport_ID nvarchar(255),
@paramPartNumberString nvarchar(MAX) = NULL,
@paramOtherColumnsString nvarchar(MAX) = NULL
AS
BEGIN
DECLARE @tempPartTable TABLE (
[Report_ID] [nvarchar](255) NOT NULL,
[PartNumberOrdered] [nvarchar](255) NOT NULL,
[OtherColumns] [nvarchar](255) NULL)
DECLARE @WorkingPartNumberString nvarchar(255),
@WorkingOtherColumnsString nvarchar(255)
-- Magic to parse the semicolon delimited parameters omitted
WHILE (PartsRemainingToParse)
BEGIN
INSERT INTO @tempPartTable (
[Report_ID],
[PartNumberOrdered],
[OtherColumns])
VALUES (
@paramReport_ID,
@WorkingPartNumberString,
@WorkingOtherColumnsString)
END
MERGE [Report_to_Parts]
USING @tempPartTable AS [Source]
ON (
[Report_to_Parts].[Report_ID] = @paramReport_ID AND
[Report_to_Parts].[PartNumberOrdered] = [Source].[PartNumberOrdered])
WHEN NOT MATCHED BY TARGET
THEN INSERT(
[Report_ID],
[PartNumberOrdered],
[OtherColumns])
VALUES (
@paramReport_ID,
[Source].[PartNumberOrdered],
[Source].[OtherColumns])
WHEN MATCHED
THEN UPDATE SET [OtherColumns]=[Source].[OtherColumns]
WHEN NOT MATCHED BY SOURCE AND [Report_to_Parts].[Report_ID] = @paramReport_ID
THEN DELETE;
END
目前工作的投入和結果,假設與123456 [REPORT_ID]部分不存在在[Report_to_Parts],但其他一些條目做:
EXEC MergeReport_sp
@paramReport_ID = N'123456',
@paramPartNumberString = N'Part 1;abcd-efg;Part 3;'
@paramOtherColumnsString = N'There are many;other columns;but I simplified;'
SELECT * FROM [Report_to_Parts] WHERE [Report_ID] = N'123456'
---------------------------------------------------------
| ID | Report_ID | PartNumberOrdered | OtherColumns |
| 05 | 123456 | Part 1 | There are many |
| 06 | 123456 | abcd-efg | other columns |
| 07 | 123456 | Part 3 | but I simplified |
EXEC MergeReport_sp
@paramReport_ID = N'123456',
@paramPartNumberString = N'Part 1;Part 3;New Part;'
@paramOtherColumnsString = N'Updates;Work;Too;'
SELECT * FROM [Report_to_Parts] WHERE [Report_ID] = N'123456'
-----------------------------------------------------
| ID | Report_ID | PartNumberOrdered | OtherColumns |
| 05 | 123456 | Part 1 | Updates |
| 07 | 123456 | Part 3 | Work |
| 08 | 123456 | New Part | Too |
但因爲它試圖立足東西了PartNumberOrdered以下故障:
EXEC MergeReport_sp
@paramReport_ID = N'123456',
@paramPartNumberString = N'Part 1;Part 1;'
@paramOtherColumnsString = N'Thing 1;Thing 2;'
現在我需要它能夠很好地處理與多個部件共享的部件號報告。關閉InfoPath和/或SharePoint不是一種選擇,也不會刪除分號解析方面。我正在考慮的選項:
- 每次調用存儲過程時,從[Report_to_Parts]中刪除具有匹配[Report_ID]的所有行並插入所有的@tempPartTable行。這是我想要進行數據分析的最終結果,但我擔心這非常低效,並且在使用系統時[ID]會變得不必要的大。
- 更改[Report_to_Parts],使其具有[ID]和[Report_ID]的組合鍵,並找出每個[Report_ID]從[1]開始以[ID]自動遞增的方式,然後刪除並插入。
- 從[Report_to_Parts]中爲[ID],
SELECT
添加一列到[tempPartTable]以獲取此[Report_ID]的表中已有的部件的[ID] s,並基於此設置@tempPartTable [ID] s,並且MERGE
在[ID]上。 - 更改[Report_to_Parts],所以它有一個組合鍵,爲[ID]添加一列到@tempPartTable,自動從1開始遞增,
MERGE
由[ID]和[Report_ID]添加一列。
我很難想出3代碼,我也絕對可以接受其他想法。 Here's an earlier question I asked about this same system.
是否有可能創建一個視圖,可以代表分隔數據一個實際的表?那麼你可以使用該表作爲更自然的方式來查詢數據庫嗎?老實說,我不確定視圖部分是否可能,因爲它似乎需要一個存儲過程來進行解析。 – KingOfAllTrades
@KingOfAllTrades沒有'WHILE'循環我敢肯定它不可能解析字符串。但我的解析工作很好。這與我正在努力的結果有什麼關係。 –
這也是我所懷疑的,但是也許你覺得你有一個絕招。我對此感興趣,因爲我也將SharePoint用作數據庫。票務系統,應用程序配置和簡單的CRUD應用程序。這些工作很好,你可以很容易地查詢數據庫,一旦你得到列表GUID。你能發佈表格變量和其他表格的樣本數據以及預期結果嗎? – KingOfAllTrades