我目前正在尝试将数据输入 SQL 的不同方法,昨天使用 BCP 遇到了一个问题,尽管我解决了这个问题,但由于没有非常有用的错误信息,这让我想起了使用 SSIS 包。我觉得对于我喜欢的工作方式,我会更乐意将整个数据行加载到临时表中(无论是固定宽度还是定界)(使用 BCP 或批量插入),然后对数据行进行操作,而不是试图强制它们输入正在进入 SQL 的列。
因此,我想找到一种方法,允许我在将数据插入其目标之前拆分和验证(检查数据类型)数据,并将任何错误的数据行写入另一个表,以便我可以决定如何处理它们.
我已经拼凑了一个脚本来模拟场景,importedData 表将是我的 BCP 或 BULK INSERT 的输出。ImportedData 中的所有数据都需要在 Presenters 或 RejectedData 表中结束。
我需要一种可以合理扩展的方法,现实生活中的情况可能更像是 40 列和 2000 万行数据,所以我想我必须一次处理 10,000 行。
SQL Server 2012 具有新的 try_parse 函数,这可能会有所帮助,但我需要能够在 2005 和 2008 机器上执行此操作。
IF OBJECT_ID (N'ImportedData', N'U') IS NOT NULL DROP TABLE dbo.ImportedData
CREATE TABLE dbo.ImportedData (RowID INT IDENTITY(1,1), DataRow VARCHAR(MAX))
IF OBJECT_ID (N'Presenters', N'U') IS NOT NULL DROP TABLE dbo.Presenters
CREATE TABLE dbo.Presenters (PresenterID INT, FirstName VARCHAR(10), LastName VARCHAR(10))
IF OBJECT_ID (N'RejectedData', N'U') IS NOT NULL DROP TABLE dbo.RejectedData
CREATE TABLE dbo.RejectedData (DataRow VARCHAR(MAX))
-- insert as fixed-width
INSERT INTO dbo.ImportedData(DataRow)
SELECT '1 Bruce Forsythe '
UNION ALL SELECT '2 David Dickinson '
UNION ALL SELECT 'X BAD DATA'
UNION ALL SELECT '3 Keith Chegwin '
-- insert as CSV
/*INSERT INTO dbo.ImportedData(DataRow)
SELECT '1,Bruce,Forsythe'
UNION ALL SELECT '2,David,Dickinson'
UNION ALL SELECT 'X,BAD,DATA'
UNION ALL SELECT '3,Keith,Chegwin'
*/
---------- DATA PROCESSING -------------------------------
SELECT
SUBSTRING(DataRow,1,3) AS ID,
SUBSTRING(DataRow,4,10) AS FirstName,
SUBSTRING(DataRow,14,10) AS LastName
FROM
ImportedData
---------- DATA PROCESSING -------------------------------
SELECT * FROM ImportedData
SELECT * FROM Presenters
SELECT * FROM RejectedData