2016-08-25 75 views
0

我写了动态SQL存储过程会抛出时,我把它称为一个错误,当参数:SQL服务器:dymanic SQL错误:“CREATE VIEW”必须是查询批次中的第一条语句

IF OBJECT_ID('[dbo].[find_most_frequent]') IS NOT NULL 
    DROP PROCEDURE [dbo].[find_most_frequent] 
GO 

CREATE PROCEDURE [dbo].[find_most_frequent] 
     @table_in VARCHAR(100), 
     @table_out VARCHAR(100), 
     @col_group VARCHAR(100), 
     @col_2 VARCHAR(100) 
AS 
BEGIN 
    DECLARE @sql NVARCHAR(4000); 

    SET @sql = 
    --start of code 
    'USE CTR 
GO 

IF OBJECT_ID(N''[dbo].[two_columns]'', N''V'') IS NOT NULL 
    DROP VIEW [dbo].[two_columns]; 

IF OBJECT_ID(N''[dbo].[count_in_group]'', N''V'') IS NOT NULL 
    DROP VIEW [dbo].[count_in_group]; 

IF OBJECT_ID(N''[dbo].[rank_in_group]'', N''V'') IS NOT NULL 
    DROP VIEW [dbo].[rank_in_group]; 

IF OBJECT_ID(N''[dbo].[most_frequent_in_group]'', N''V'') IS NOT NULL 
    DROP VIEW [dbo].[most_frequent_in_group]; 
GO 

CREATE VIEW [dbo].[two_columns] AS 
SELECT ' + 
     @col_group + 
     ' ,' + @col_2 + 
    ' FROM ' + @table_in + 
' 
GO 

CREATE VIEW [dbo].[count_in_group] AS 
SELECT DISTINCT 
     * 
     ,COUNT(*) OVER(PARTITION BY ' + @col_group + ', ' + @col_2 + ') AS freq 
    FROM [dbo].[two_columns] 
GO 

CREATE VIEW [dbo].[rank_in_group] AS 
SELECT * 
     ,ROW_NUMBER() OVER (PARTITION BY ' + @col_group + ' ORDER BY freq DESC) AS rank_in_group 
    FROM [dbo].[count_in_group] 
GO 

CREATE VIEW [dbo].[most_frequent_in_group] AS 
SELECT * 
    FROM [dbo].[rank_in_group] 
    WHERE rank_in_group = 1 
GO 

SELECT * 
    INTO ' + @table_out + 
    ' FROM [dbo].[most_frequent_in_group] 
GO' 
--end of code  
    print @sql 
    EXEC SP_EXECUTESQL @sql 
END 
GO 

--call it 
EXEC [dbo].[find_most_frequent] 
     @table_in = '[dbo].[table_1]' 
     ,@table_out = '[dbo].[table_out]' 
     ,@col_group = '[col_A]' 
     ,@col_2 = '[col_B]' 
GO 

错误:

Msg 102, Level 15, State 1, Line 81
Incorrect syntax near 'GO'.
Msg 102, Level 15, State 1, Line 91
Incorrect syntax near 'GO'.
Msg 111, Level 15, State 1, Line 93
'CREATE VIEW' must be the first statement in a query batch.
Msg 111, Level 15, State 1, Line 97
'CREATE VIEW' must be the first statement in a query batch.
Msg 111, Level 15, State 1, Line 104
'CREATE VIEW' must be the first statement in a query batch.
Msg 111, Level 15, State 1, Line 110
'CREATE VIEW' must be the first statement in a query batch.
Msg 102, Level 15, State 1, Line 114
Incorrect syntax near 'GO'.

,行号是没用的,因为他们是我的代码结束后线...

在此过程中我打印@sql看一看。我复制打印的代码并粘贴到另一个查询中,它工作。 - 所以我完全不知道如何现在进行调试....

USE CTR 
GO 

IF OBJECT_ID(N'[dbo].[two_columns]', N'V') IS NOT NULL 
    DROP VIEW [dbo].[two_columns]; 

IF OBJECT_ID(N'[dbo].[count_in_group]', N'V') IS NOT NULL 
    DROP VIEW [dbo].[count_in_group]; 

IF OBJECT_ID(N'[dbo].[rank_in_group]', N'V') IS NOT NULL 
    DROP VIEW [dbo].[rank_in_group]; 

IF OBJECT_ID(N'[dbo].[most_frequent_in_group]', N'V') IS NOT NULL 
    DROP VIEW [dbo].[most_frequent_in_group]; 
GO 

CREATE VIEW [dbo].[two_columns] AS 
SELECT [hash_vcc] ,[legal_name] FROM [dbo].[ctr_vendor_pay] 
GO 

CREATE VIEW [dbo].[count_in_group] AS 
SELECT DISTINCT 
     * 
     ,COUNT(*) OVER(PARTITION BY [hash_vcc], [legal_name]) AS freq 
    FROM [dbo].[two_columns] 
GO 

CREATE VIEW [dbo].[rank_in_group] AS 
SELECT * 
     ,ROW_NUMBER() OVER (PARTITION BY [hash_vcc] ORDER BY freq DESC) AS rank_in_group 
    FROM [dbo].[count_in_group] 
GO 

CREATE VIEW [dbo].[most_frequent_in_group] AS 
SELECT * 
    FROM [dbo].[rank_in_group] 
    WHERE rank_in_group = 1 
GO 

SELECT * 
    INTO [dbo].[hashvcc_2_legalname] FROM [dbo].[most_frequent_in_group] 
GO 

有人可以帮忙吗?任何帮助的赞赏。由于

UPDATE

我分裂每个CREATE VIEW成不同的字符串,并分别EXEC他们。 - 使用BEGINEND来包装每个CREATE VIEW不起作用。

现在还是这片抛出错误:

CREATE VIEW [dbo].[most_frequent_in_group] AS 
SELECT * 
    FROM [dbo].[rank_in_group] 
    WHERE rank_in_group = 1 

SELECT * 
    INTO [dbo].[hashvcc_2_legalname] 
    FROM [dbo].[most_frequent_in_group] 

错误:

Incorrect syntax near the keyword 'SELECT'.

当我运行CREATE VIEWSELECT分开它的工作原理。

得到了答案:VIEW必须是在一个批处理中唯一的语句 - 感谢@ZLK

+0

不幸的是,由于'GO'实际上并不是T-SQL(请参阅此处的注释:https://msdn.microsoft.com/en-us/library/ms188037.aspx),您将不得不考虑替代方法分解每个部分并分别执行它们。 – ZLK

+0

谢谢@ZLK! BEGIN END工作吗? –

+0

在动态sql?是的......但不适用于创建批次开始时所需的视图和其他类似内容。 – ZLK

回答

1

关于GO

GO is not a Transact-SQL statement; it is a command recognized by the sqlcmd and osql utilities and SQL Server Management Studio Code editor.

分裂您查询到单独的请求:

EXEC sp_executesql N' 
USE CTR 

IF OBJECT_ID(N''[dbo].[two_columns]'', N''V'') IS NOT NULL 
    DROP VIEW [dbo].[two_columns]; 
IF OBJECT_ID(N''[dbo].[count_in_group]'', N''V'') IS NOT NULL 
    DROP VIEW [dbo].[count_in_group]; 
IF OBJECT_ID(N''[dbo].[rank_in_group]'', N''V'') IS NOT NULL 
    DROP VIEW [dbo].[rank_in_group]; 
    IF OBJECT_ID(N''[dbo].[most_frequent_in_group]'', N''V'') IS NOT NULL 
    DROP VIEW [dbo].[most_frequent_in_group];' 

EXEC sp_executesql N' 
CREATE VIEW [dbo].[two_columns] AS 
SELECT [hash_vcc] ,[legal_name] FROM [dbo].[ctr_vendor_pay]' 

... 

等等。

+0

我明白了。谢谢@背靠! BEGIN END工作吗?字符串必须在N之前?谢谢 - –

+0

@YZhang'BEGIN'和'END'是有效的TSQL语法。 'N'表示该字符串是unicode。存储过程'sp_executesql'仅适用于unicode – Backs

相关问题