為什麼我的數據庫結構和 SELECT 操作會生成 NULL?
我對數據庫問題沒有太多經驗,所以請原諒文字牆,我相信上下文對於理解問題和目標很重要。
我每天都從另一個系統收到一個 CSV 文件,我希望將其保留在 Microsoft SQL Server 上執行的數據庫中。為此,我每天安排一個 PowerShell 腳本,該腳本使用 bcp 實用程序將 CSV ( accounts.csv
accounts_stage
)“載入”到具有 CSV 文件“精確”佈局的表 ( ) 中。此外,我將時間戳“寫入”到另一個表 (import_stage
) 中。該accounts_stage
表有一個觸發器集,並且 bcp 被配置為觸發該觸發器。導入完成後,我想“規範化”數據。對於一個基本範例,假設這僅涉及契約編號(在 CSV 文件中名為“Vnr”的欄位),它是一個字元串。我有另一個表 (
contracts
),它被觸發器填充:INSERT INTO dzp.contractid(vnr) SELECT DISTINCT a.Vnr FROM dzp.accounts_stage a WHERE NOT EXISTS( SELECT id.vnr FROM dzp.contractid id )
這應該並且似乎可以完成,添加曾經導入到表中的所有契約編號
contractids
。contractids.contractId
是 BIGINT PRIMARY KEY、IDENTITY 和自動增量。我將導入元數據添加到我的表中,如下所示:
CREATE TABLE #IMPORTMETADATA ([importid] bigint ,[generated_timestamp] datetime ,[imported_timestamp] datetime ) INSERT INTO #IMPORTMETADATA SELECT TOP 1 [importid], [timestamp_import], [generated_timestamp] FROM [QGTAA].[dzp].[import] ORDER BY [timestamp_import] DESC
接下來,觸發器應該插入數據 FROM
accounts_stage
INTOaccounts
,以便contractId
替換(從原始字元串表示到contracts
表的 PRIMARY KEY)。INSERT INTO [dzp].[accounts] ([Udnr] ,[ContractId] -- snip ,[generated_timestamp] ,[importid] ) SELECT a.[Udnr], cid.contractId, -- snip meta.[generated_timestamp], meta.[importid] FROM [QGTAA].[dzp].[accounts_stage] a LEFT JOIN dzp.contractid cid ON cid.vnr = a.Vnr CROSS JOIN #IMPORTMETADATA meta
但是,這最後一步失敗了,因為最後一個塊中的 SELECT 操作產生了
contractId
IS NULL 的行,這是我沒有預料到的。現在我認為問題出在 LEFT JOIN 的某個地方,但我不確定為什麼。問題
- 有人可以在這個特定問題上為我指出正確的方向嗎?
- 我對數據庫沒有太多經驗,這甚至是一種實現我想要的理智的方式,還是一種完全瘋狂的方式?有沒有更好的辦法?
謝謝!
你的第一個有問題
NOT EXISTS
。讓我們看一下您目前的查詢:INSERT INTO dzp.contractid(vnr) SELECT DISTINCT a.Vnr FROM dzp.accounts_stage a WHERE NOT EXISTS( SELECT id.vnr FROM dzp.contractid id )
因此,這裡發生的情況是
NOT EXISTS
,您正在使用的僅當dzp.contractid
表為空時才會返回 true。一旦它有一行(或更多),NOT EXISTS
就會返回false
主表的每一行,因為SELECT id.vnr FROM dzp.contractid
有一個結果集,並且您最終會在表中插入重複的值。您需要做的是將此子查詢與主表相關聯:
INSERT INTO dzp.contractid(vnr) SELECT DISTINCT a.Vnr FROM dzp.accounts_stage a WHERE NOT EXISTS( SELECT id.vnr FROM dzp.contractid id WHERE id.vnr = a.vnr );
此外,
CROSS JOIN
最新導入的數據對我來說沒有多大意義,而且您沒有檢查數據是否已存在於accounts
表中的事實也沒有。