动态SQL的挑战

时间:2017-12-21 13:57:41

标签: sql-server stored-procedures dynamic

我有一个生成动态SQL的过程,在查询excel电子表格时会创建一个insert into语句。

可以将消息屏幕中的结果打印粘贴到ssms窗口并执行。当我尝试从存储过程中执行SQL时,我得到如下语法错误:

'SELECT  * into TestClient FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=YES;Database=G:\CustomerETL\Employee\PendingETL\ETLEmployeexls.xls;', [Sheet1$])'
Msg 102, Level 15, State 1, Line 15
Incorrect syntax near 'SELECT  * into TestClient FROM OPENROWSET('.

以下是整个存储过程。我知道问题出现在滴答声中(在创建动态SQL的SET块中,我只能找出丢失滴答的位置。

这是proc:

USE [ETL]
GO
/****** Object:  StoredProcedure [dbo].[ImportExcelSheetForCustomerEmployeeUpdate2]    Script Date: 12/19/2017 4:03:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ImportExcelSheetForCustomerEmployeeUpdate2](@BatchID int)    

as

--EXEC ImportExcelSheetForCustomerEmployeeUpdate 2



/*  --  TRUNCATE TABLE FilesToImport
UPDATE FilesToImport
SET StatusID = 1
*/

-- Jeffery Williams
-- 12/18/2017

DECLARE  @FileID int
    ,@ETLFilename varchar(250)
    ,@ClientName varchar(100)
    ,@FileType varchar(5)
    ,@ColumnCount int
    ,@RowsToETL int
    ,@StatusID int
    ,@Processed bit = 0
    ,@Count int
    ,@SQL nvarchar(4000)
    ,@Sheetname varchar(50) = '[Sheet1$]'
    ,@CMDSQL as varchar(4000)
    ,@SQLCmd NVARCHAR(MAX)


SELECT *
FROM FilesToImport

BEGIN

SELECT @Count = count(*)
FROM FilesToImport
WHERE BatchID = @BatchID
AND StatusID = 1

END

PRINT 'Count of records to process: ' + cast(@Count as varchar)

WHILE @Count > 0
BEGIN

BEGIN

SELECT TOP 1 @FileID = FileID, @ETLFilename = ETLFilename, @ClientName = ClientName
        ,@FileType = FileType, @ColumnCount = ColumnCount, @RowsToETL = RowsToETL
FROM FilesToImport
WHERE StatusID = 1
AND BatchID = @BatchID

END

-- Rename the file

set @CMDSQL = 'rename G:\CustomerETL\Employee\PendingETL\' + @ETLFilename + '  ETLEmployeexls.xls'
exec master..xp_cmdshell @CMDSQL 

--PRINT cast(@cmdsql as varchar(4000))


-- Ciode below generates our select. Need to add an INTO clause and create a staging table for each import. Prior to this step we need to rename the file.

    SET @SQL = ''''
    SET @SQL = @SQL + 'SELECT  * into ' + coalesce(@ClientName, 'TestClient') + ' FROM OPENROWSET('

    SET @SQL = @SQL + ''''

    SET @SQL = @SQL + '''' + 'Microsoft.ACE.OLEDB.12.0' + '''' --+ ', '
--  Excel 12.0;HDR=NO;Database=g:\UnZip\ImportSampleXLSX.xlsx;' + ''

    SET @SQL = @SQL + '''' + ', '

    SET @SQL = @SQL + '''' + '''Excel 12.0;HDR=YES;Database=G:\CustomerETL\Employee\PendingETL\ETLEmployeexls.xls;''' + '''' + ', ' + @Sheetname + ')'

    SET @SQL = @SQL + ''''

PRINT cast(@SQL as varchar(8000))


EXEC sp_executesql @SQL


set @CMDSQL = 'rename G:\CustomerETL\Employee\PendingETL\ETLEmployeexls.xls ' + @ETLFilename 
exec master..xp_cmdshell @CMDSQL 


UPDATE FilesToImport
SET StatusID = 2
WHERE FileID = @FileID


/*      --  TRUNCATE TABLE FilesToImport
UPDATE FilesToImport
SET StatusID = 1
*/   

SET @Count = (@Count - 1)
CONTINUE
END

1 个答案:

答案 0 :(得分:0)

我发布这个作为答案,但它应该是评论。当我尝试将其添加为评论时StackOveflow一直认为我试图将@count添加为电子邮件目标。

在您的代码中:

WHILE @Count> 0 BEGIN

BEGIN

SELECT TOP 1 @FileID = FileID,@ USERFilename = ETLFilename,@ ClientName = ClientName         ,@ FileType = FileType,@ ColCount = ColumnCount,@ RowToETL = RowsToETL FROM FilesToImport WHERE StatusID = 1 AND BatchID = @BatchID

END

您没有更新@count的值。这将永远不会循环或循环。您可能想要添加一个语句(在结束之前),例如: 设置@count = @@ rowcount;