【发布时间】:2022-01-25 17:03:06
【问题描述】:
我有一个像这样的存储过程:
CREATE PROCEDURE [dbo].[sp_writeBulk]
@usersID NVARCHAR(30)
,@fileName NVARCHAR(50)
,@nameMeasuringPoint NVARCHAR(30)
,@filesID NVARCHAR(30)
,@filePath NVARCHAR(1000)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION
DECLARE
@timestamp DATETIME2(3) = SYSDATETIME()
,@nameMeasuringPointID INT
,@sql_select NVARCHAR(1000)
,@sql_insert NVARCHAR(1000)
IF OBJECT_ID(N'tempdb..#tmp') IS NOT NULL
BEGIN
DROP TABLE #tmp
END
CREATE TABLE #tmp
(
A VARCHAR(30)
,B VARCHAR(30)
,C VARCHAR(30)
)
SET @sql_insert = N'BULK INSERT #tmp
FROM @filePath
WITH
(
FIELDTERMINATOR = '';'',
ROWTERMINATOR = ''\n'',
ROWS_PER_BATCH = 10000,
TABLOCK
)'
EXEC sp_executesql @sql_insert,
N'@filePath NVARCHAR(1000)', @filePath;
-- get @nameMeasuringPointID
SET @sql_select = N'SELECT @nameMeasuringPointID = mm.MeasuringPointID FROM dbo.MeasuringPoints AS mm
WHERE mm.LocationName = @nameMeasuringPoint'
EXEC sp_executesql @sql_select,
N'@nameMeasuringPoint NVARCHAR(30), @nameMeasuringPointID INT OUTPUT', @nameMeasuringPoint, @nameMeasuringPointID OUTPUT;
INSERT INTO dbo.Readings(UsersID, FilesID, A, B, C, FileName, XDateTime, NameMeasuringPointID)
SELECT @usersID, @filesID, A, B, C, @fileName, @timestamp, @nameMeasuringPointID
FROM #tmp;
DROP TABLE #tmp;
IF @@ERROR <> 0
BEGIN
GOTO error;
END;
COMMIT TRANSACTION;
RETURN 0;
error:
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION;
END;
RETURN 1;
END;
GO
GRANT EXEC ON [dbo].[sp_writeBulk] TO myuser;
GO
当我像这样执行它时:
exec sp_writeBulk '2', 'name_test', 'MP Test', '1', 'C:\Users\myuser\Downloads\myTest.csv'
我明白了:
“@filePath”附近的语法不正确。
我不明白它有什么问题?
【问题讨论】:
-
为什么
@sql_select是动态的,好像没必要。旁白:我建议你放弃那个可怕的错误处理,或者用TRYCATCH代替,或者更好:根本不处理错误,只需使用SET XACT_ABORT ON;来确保事务回滚 -
谢谢,您的建议都被采纳了
标签: sql sql-server database tsql bulkinsert