好的,我已经与这个问题作斗争了将近一个星期,我一生都无法弄清楚问题是什么。
问题:BCP 实用程序创建 txt 文件,但之后没有任何反应。该文件只是坐在那里并且是空白的。BCP 几乎挂起。我必须结束进程才能停止它。BCP 命令位于存储过程中,该存储过程位于作业步骤中的事务中。如果我使用 sproc 本身并在 Management Studio 中运行它,则该文件的创建没有问题。如果我创建一个 SQL 作业并只放置运行 BCP 命令的存储过程,它也可以工作。
这是工作步骤:
BEGIN TRANSACTION
BEGIN TRY
EXEC dbo.DataManipulation1
EXEC dbo.DataManipulation2
EXEC dbo.DataManipulation3
EXEC dbo.DataManipulation4
EXEC dbo.DataManipulation5
EXEC dbo.spCreateFiles 0
EXEC dbo.spSendEmail 'PASS'
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
EXEC dbo.spGetDatabaseErrorInfo
EXEC dbo.spCreateFiles 1
EXEC dbo.spSendEmail 'FAIL'
END CATCH
这是 spCreateFiles 存储过程。高级概述:Sproc 生成系统文件夹,然后对 txt 文件进行查询。而已。如果传递给sproc的参数为0,它将根据sproc的执行生成文件,如果参数不为0,则生成空白文件。一共4个文件。BCP 命令的用户名和密码因显而易见的原因而被删除。从我在线阅读的一些内容来看,这可能是因为某些东西正在锁定文件……可能是存储过程或 SQL 作业,甚至是事务,然后当 BCP 实用程序尝试使用它时,什么也没有发生。
ALTER PROCEDURE [dbo].[spCreateFiles] @errorCode BIT
AS
BEGIN
BEGIN TRY
SET NOCOUNT ON;
DECLARE @year CHAR(4)
DECLARE @month CHAR(2)
DECLARE @day CHAR(2)
DECLARE @rootDir VARCHAR(200)
DECLARE @yearDir VARCHAR(200)
DECLARE @monthDir VARCHAR(200)
DECLARE @dayDir VARCHAR(200)
DECLARE @dirsTable TABLE (directory VARCHAR(200))
DECLARE @baseFileName VARCHAR(8)
DECLARE @detailFile VARCHAR(500)
DECLARE @detailNydFile VARCHAR(500)
DECLARE @summaryFile VARCHAR(500)
DECLARE @summaryNydFile VARCHAR(500)
DECLARE @cmdQueryout VARCHAR(2000)
SET @rootDir = 'C:\Test\'
SET @year = DATEPART(YEAR, GETDATE())
SET @month = RIGHT('00' + CONVERT(NVARCHAR(2), DATEPART(MONTH, GETDATE())), 2)
SET @day = RIGHT('00' + CONVERT(NVARCHAR(2), DATEPART(DAY, GETDATE())), 2)
SET @yearDir = @rootDir + @year + '\'
SET @monthDir = @rootDir + @year + '\' + @year + @month + '\'
SET @dayDir = @rootDir + @year + '\' + @year + @month + '\' + @year + @month + @day + '\'
SET @baseFileName = @year + @month + @day
PRINT @rootDir
PRINT @year
PRINT @month
PRINT @day
PRINT @yearDir
PRINT @monthDir
PRINT @dayDir
PRINT @baseFileName
INSERT INTO @dirsTable
EXEC master.dbo.xp_subdirs
@rootDir
IF NOT EXISTS ( SELECT directory
FROM @dirsTable
WHERE directory = @year )
EXEC master.sys.xp_create_subdir
@yearDir
DELETE FROM @dirsTable
INSERT INTO @dirsTable
EXEC master.dbo.xp_subdirs
@yearDir
IF NOT EXISTS ( SELECT directory
FROM @dirsTable
WHERE directory = @month )
EXEC master.sys.xp_create_subdir
@monthDir
DELETE FROM @dirsTable
INSERT INTO @dirsTable
EXEC master.dbo.xp_subdirs
@monthDir
IF NOT EXISTS ( SELECT directory
FROM @dirsTable
WHERE directory = @day )
EXEC master.sys.xp_create_subdir
@dayDir
DELETE FROM @dirsTable
SET @detailFile = @dayDir + @baseFileName + ' Detail.txt'
SET @detailNydFile = @dayDir + @baseFileName + ' Detail_NYD.txt'
SET @summaryFile = @dayDir + @baseFileName + ' Summary.txt'
SET @summaryNydFile = @dayDir + @baseFileName + ' Summary_NYD.txt'
PRINT @detailFile
PRINT @detailNydFile
PRINT @summaryFile
PRINT @summaryNydFile
IF @errorCode = 0
BEGIN
PRINT 'Error Code: ' + CAST(@errorCode AS CHAR(1))
SET @cmdQueryout = 'bcp "EXEC DB_NAME.dbo.spGetDetailRecords" queryout "' + @detailFile + '" -c -Uusername -Ppassword'
PRINT @cmdQueryout
EXEC master..xp_cmdshell
@cmdQueryout
SET @cmdQueryout = 'bcp "EXEC DB_NAME.dbo.spGetDetailNYDRecords" queryout "' + @detailNydFile + '" -c -Uusername -Ppassword'
PRINT @cmdQueryout
EXEC master..xp_cmdshell
@cmdQueryout
SET @cmdQueryout = 'bcp "EXEC DB_NAME.dbo.spGetSummaryRecords" queryout "' + @summaryFile + '" -c -Uusername -Ppassword'
PRINT @cmdQueryout
EXEC master..xp_cmdshell
@cmdQueryout
SET @cmdQueryout = 'bcp "EXEC DB_NAME.dbo.spGetSummaryNYDRecords" queryout "' + @summaryNydFile + '" -c -Uusername -Ppassword'
PRINT @cmdQueryout
EXEC master..xp_cmdshell
@cmdQueryout
END
ELSE
BEGIN
SET @cmdQueryout = 'bcp "SELECT NULL" queryout "' + @detailFile + '" -c -Uusername -Ppassword'
EXEC master..xp_cmdshell
@cmdQueryout
SET @cmdQueryout = 'bcp "SELECT NULL" queryout "' + @detailNydFile + '" -c -Uusername -Ppassword'
EXEC master..xp_cmdshell
@cmdQueryout
SET @cmdQueryout = 'bcp "SELECT NULL" queryout "' + @summaryFile + '" -c -Uusername -Ppassword'
EXEC master..xp_cmdshell
@cmdQueryout
SET @cmdQueryout = 'bcp "SELECT NULL" queryout "' + @summaryNydFile + '" -c -Uusername -Ppassword'
EXEC master..xp_cmdshell
@cmdQueryout
END
END TRY
BEGIN CATCH
EXEC dbo.spGetDatabaseErrorInfo
END CATCH
END