【问题标题】:Incorrect syntax near ','. when using Exec',' 附近的语法不正确。使用 Exec 时
【发布时间】:2017-02-22 13:53:20
【问题描述】:

问题: ',' 附近的语法不正确。 (过程 spAddNewDataToHoldingTable,第 71 行)

目标:将数据插入表(我通过另一个存储过程创建)

想法:我尝试了一些撇号组合,如果我让 SQL 运行,那么这意味着在第一个值之前没有撇号,因此会出错。

我希望一个撇号在错误的地方就是它的全部。

如果我没有变量名,我可以在没有 EXEC 的情况下运行,但我也想让它变得安全。

代码:

USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE  [dbo].[spAddNewDataToHoldingTable] 

@sTableName varchar(50),
@sPMNUM varchar(8),
@sUPRN varchar(510) ,
@sSurveyDate Date,
@sVFMDISCIPLINE varchar(4) ,
@sVFMDISCIPLINEELEMENT varchar(510) ,
@sWorkOrder varchar(510) ,
@sNextSurveyDue  Date ,
@sRiskCategory varchar(510) ,
@sDocURL varchar(MAX) ,
@sDocLinks varchar(MAX) ,
@sVINCIRISKLevel varchar(510) ,
@sRemedialActionWO varchar(510) ,
@sRemedialActionDate date,
@sComments varchar(MAX) ,
@sRISKNUM varchar(510) ,
@sRISKOWNER varchar(510) ,
@sSurveyorsComments varchar(MAX) ,
@sRecommendations varchar(510) ,
@sStatusOfIssue int ,
@sClientContract varchar(12) ,
@sJPNUM varchar(12)


AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
SET NOCOUNT ON;

DECLARE @sTablename_ AS varchar(max)

SET @sTablename_ = LTRIM(RTRIM(@sTableName))

DECLARE @sql NVARCHAR(2500)

SET @sql = '
INSERT INTO ' + @sTablename_  + '
(
PMNUM,
UPRN,
VFMDISPLINE,
VFMDISPLINEELEMENT,
WorkOrder,
RiskCategory,
DocURL,
DocLinks,
VINCIRISKLevel,
RemedialActionWO,
Comments,
RISKNUM,
RISKOWNER,
SurveyorsComments,
Recommendation,
StatusOfIssue,
ClientContract,
JPNUM,
RemedialActionDate  ,
SurveyDate ,
NextSurveyDate  
)

VALUES

('''

+ ''' + QUOTENAME(@sPMNUM) + '''
, ''' + QUOTENAME(@sUPRN) + '''
, ''' + QUOTENAME(@sVFMDISCIPLINE) + '''
, ''' + QUOTENAME(@sVFMDISCIPLINEELEMENT) + '''
, ''' + QUOTENAME(@sWorkOrder) + '''
, ''' + QUOTENAME(@sRiskCategory) + '''
, ''' + QUOTENAME(@sDocURL) + '''
, ''' + QUOTENAME(@sDocLinks) + '''
, ''' + QUOTENAME(@sVINCIRISKLevel) + '''
, ''' + QUOTENAME(@sRemedialActionWO) + '''
, ''' + QUOTENAME(@sComments) + '''
, ''' + QUOTENAME(@sRISKNUM) + '''
, ''' + QUOTENAME(@sRISKOWNER) + '''
, ''' + QUOTENAME(@sSurveyorsComments) + '''
, ''' + QUOTENAME(@sRecommendations) + '''
, ''' + QUOTENAME(@sStatusOfIssue + '''
, ''' + QUOTENAME(@sClientContract) + '''
, ''' + QUOTENAME(@sJPNUM) + '''
, ''' + QUOTENAME(@sRemedialActionDate) + '''
, ''' + QUOTENAME(@sSurveyDate) + '''
, ''' + QUOTENAME(@sNextSurveyDue) + '''
+ ''')'''

EXEC (@sql)

END

参考:

SQL Server incorrect syntax near ')' Incorrect syntax near '(' and near '='

【问题讨论】:

  • 您的值列表包含不属于 SQL 字符串的逗号(它们没有被正确引用)
  • EXEC (@sql) 替换为SELECT (@sql)print @sql
  • 唯一动态的是你的表名,表明你“做错了”。您已经创建了动态表(具有相同的列)而不是正确的数据库结构。

标签: sql sql-server stored-procedures sql-server-2012


【解决方案1】:

您不需要在所有这些上使用quotename(),它只是将它们包装在方括号中。

别忘了convert() 你的date 数据类型到varchar

ALTER PROCEDURE  [dbo].[spAddNewDataToHoldingTable] 

@sTableName varchar(50),
@sPMNUM varchar(8),
@sUPRN varchar(510) ,
@sSurveyDate Date,
@sVFMDISCIPLINE varchar(4) ,
@sVFMDISCIPLINEELEMENT varchar(510) ,
@sWorkOrder varchar(510) ,
@sNextSurveyDue  Date ,
@sRiskCategory varchar(510) ,
@sDocURL varchar(MAX) ,
@sDocLinks varchar(MAX) ,
@sVINCIRISKLevel varchar(510) ,
@sRemedialActionWO varchar(510) ,
@sRemedialActionDate date,
@sComments varchar(MAX) ,
@sRISKNUM varchar(510) ,
@sRISKOWNER varchar(510) ,
@sSurveyorsComments varchar(MAX) ,
@sRecommendations varchar(510) ,
@sStatusOfIssue int ,
@sClientContract varchar(12) ,
@sJPNUM varchar(12)


AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
SET NOCOUNT ON;

DECLARE @sTablename_ AS varchar(max)

SET @sTablename_ = LTRIM(RTRIM(@sTableName))

DECLARE @sql NVARCHAR(2500)

SET @sql = '
INSERT INTO ' + @sTablename_  + '
(
PMNUM,
UPRN,
VFMDISPLINE,
VFMDISPLINEELEMENT,
WorkOrder,
RiskCategory,
DocURL,
DocLinks,
VINCIRISKLevel,
RemedialActionWO,
Comments,
RISKNUM,
RISKOWNER,
SurveyorsComments,
Recommendation,
StatusOfIssue,
ClientContract,
JPNUM,
RemedialActionDate  ,
SurveyDate ,
NextSurveyDate  
)

VALUES

('

+   '''' + @sPMNUM                + ''''
+ ', ''' + @sUPRN                 + ''''
+ ', ''' + @sVFMDISCIPLINE        + ''''
+ ', ''' + @sVFMDISCIPLINEELEMENT + ''''
+ ', ''' + @sWorkOrder            + ''''
+ ', ''' + @sRiskCategory         + ''''
+ ', ''' + @sDocURL               + ''''
+ ', ''' + @sDocLinks             + ''''
+ ', ''' + @sVINCIRISKLevel       + ''''
+ ', ''' + @sRemedialActionWO     + ''''
+ ', ''' + @sComments             + ''''
+ ', ''' + @sRISKNUM              + ''''
+ ', ''' + @sRISKOWNER            + ''''
+ ', ''' + @sSurveyorsComments    + ''''
+ ', ''' + @sRecommendations      + ''''
+ ', ''' + @sStatusOfIssue        + ''''
+ ', ''' + @sClientContract       + ''''
+ ', ''' + @sJPNUM                + ''''
+ ', ''' + convert(varchar(10),@sRemedialActionDate,120)+ ''''
+ ', ''' + convert(varchar(10),@sSurveyDate,120)        + ''''
+ ', ''' + convert(varchar(10),@sNextSurveyDue,120)     + ''''
+ ');'

EXEC (@sql)
END;

【讨论】:

    【解决方案2】:

    你添加了另一个'''

    这里更新了一个

    USE [DB]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER PROCEDURE  [dbo].[spAddNewDataToHoldingTable] 
    
    @sTableName varchar(50),
    @sPMNUM varchar(8),
    @sUPRN varchar(510) ,
    @sSurveyDate Date,
    @sVFMDISCIPLINE varchar(4) ,
    @sVFMDISCIPLINEELEMENT varchar(510) ,
    @sWorkOrder varchar(510) ,
    @sNextSurveyDue  Date ,
    @sRiskCategory varchar(510) ,
    @sDocURL varchar(MAX) ,
    @sDocLinks varchar(MAX) ,
    @sVINCIRISKLevel varchar(510) ,
    @sRemedialActionWO varchar(510) ,
    @sRemedialActionDate date,
    @sComments varchar(MAX) ,
    @sRISKNUM varchar(510) ,
    @sRISKOWNER varchar(510) ,
    @sSurveyorsComments varchar(MAX) ,
    @sRecommendations varchar(510) ,
    @sStatusOfIssue int ,
    @sClientContract varchar(12) ,
    @sJPNUM varchar(12)
    
    
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
    SET NOCOUNT ON;
    
    DECLARE @sTablename_ AS varchar(max)
    
    SET @sTablename_ = LTRIM(RTRIM(@sTableName))
    
    DECLARE @sql NVARCHAR(2500)
    
    SET @sql = '
    INSERT INTO ' + @sTablename_  + '
    (
    PMNUM,
    UPRN,
    VFMDISPLINE,
    VFMDISPLINEELEMENT,
    WorkOrder,
    RiskCategory,
    DocURL,
    DocLinks,
    VINCIRISKLevel,
    RemedialActionWO,
    Comments,
    RISKNUM,
    RISKOWNER,
    SurveyorsComments,
    Recommendation,
    StatusOfIssue,
    ClientContract,
    JPNUM,
    RemedialActionDate  ,
    SurveyDate ,
    NextSurveyDate  
    )
    
    VALUES
    
    (''' + QUOTENAME(@sPMNUM) + '''
    , ''' + QUOTENAME(@sUPRN) + '''
    , ''' + QUOTENAME(@sVFMDISCIPLINE) + '''
    , ''' + QUOTENAME(@sVFMDISCIPLINEELEMENT) + '''
    , ''' + QUOTENAME(@sWorkOrder) + '''
    , ''' + QUOTENAME(@sRiskCategory) + '''
    , ''' + QUOTENAME(@sDocURL) + '''
    , ''' + QUOTENAME(@sDocLinks) + '''
    , ''' + QUOTENAME(@sVINCIRISKLevel) + '''
    , ''' + QUOTENAME(@sRemedialActionWO) + '''
    , ''' + QUOTENAME(@sComments) + '''
    , ''' + QUOTENAME(@sRISKNUM) + '''
    , ''' + QUOTENAME(@sRISKOWNER) + '''
    , ''' + QUOTENAME(@sSurveyorsComments) + '''
    , ''' + QUOTENAME(@sRecommendations) + '''
    , ''' + QUOTENAME(@sStatusOfIssue) + '''
    , ''' + QUOTENAME(@sClientContract) + '''
    , ''' + QUOTENAME(@sJPNUM) + '''
    , ''' + QUOTENAME(@sRemedialActionDate) + '''
    , ''' + QUOTENAME(@sSurveyDate) + '''
    , ''' + QUOTENAME(@sNextSurveyDue) + ''')'
    
    EXEC (@sql)
    
    END
    

    【讨论】:

    • 检查结尾) - 我认为引号也太多了
    【解决方案3】:

    要转义单引号,您需要将其加倍。 因此 ''', ''' 将返回为 ','

    所以,你的代码应该是这样的:

    SET @sql = '
    INSERT INTO ' + @sTablename_  + '
    (
    PMNUM,
    UPRN,
    VFMDISPLINE,
    VFMDISPLINEELEMENT,
    WorkOrder,
    RiskCategory,
    DocURL,
    DocLinks,
    VINCIRISKLevel,
    RemedialActionWO,
    Comments,
    RISKNUM,
    RISKOWNER,
    SurveyorsComments,
    Recommendation,
    StatusOfIssue,
    ClientContract,
    JPNUM,
    RemedialActionDate  ,
    SurveyDate ,
    NextSurveyDate  
    )
    
    VALUES
    
    (
    ''' + QUOTENAME(@sPMNUM) + '''
    , ''' + QUOTENAME(@sUPRN) + '''
    , ''' + QUOTENAME(@sVFMDISCIPLINE) + '''
    , ''' + QUOTENAME(@sVFMDISCIPLINEELEMENT) + '''
    , ''' + QUOTENAME(@sWorkOrder) + '''
    , ''' + QUOTENAME(@sRiskCategory) + '''
    , ''' + QUOTENAME(@sDocURL) + '''
    , ''' + QUOTENAME(@sDocLinks) + '''
    , ''' + QUOTENAME(@sVINCIRISKLevel) + '''
    , ''' + QUOTENAME(@sRemedialActionWO) + '''
    , ''' + QUOTENAME(@sComments) + '''
    , ''' + QUOTENAME(@sRISKNUM) + '''
    , ''' + QUOTENAME(@sRISKOWNER) + '''
    , ''' + QUOTENAME(@sSurveyorsComments) + '''
    , ''' + QUOTENAME(@sRecommendations) + '''
    , ''' + QUOTENAME(@sStatusOfIssue) + '''
    , ''' + QUOTENAME(@sClientContract) + '''
    , ''' + QUOTENAME(@sJPNUM) + '''
    , ''' + QUOTENAME(@sRemedialActionDate) + '''
    , ''' + QUOTENAME(@sSurveyDate) + '''
    , ''' + QUOTENAME(@sNextSurveyDue) + ''')'
    

    【讨论】:

    • 为什么我的回答被否决了?它解决了 OP 关于给定查询中语法不正确的问题。
    【解决方案4】:

    我认为您不应该在这里使用动态 sql,而应该修复导致您需要多个表都具有完全相同架构的设计。但是,如果您要坚持这一点,则需要在动态 sql 中使用参数,而不是尝试到处使用单引号。并且简单地添加一组双单引号只会延迟这个问题。以下是如何使用动态 sql 执行此操作并参数化所有值。

    ALTER PROCEDURE  [dbo].[spAddNewDataToHoldingTable] 
    (
        @sTableName varchar(50),
        @sPMNUM varchar(8),
        @sUPRN varchar(510) ,
        @sSurveyDate Date,
        @sVFMDISCIPLINE varchar(4) ,
        @sVFMDISCIPLINEELEMENT varchar(510) ,
        @sWorkOrder varchar(510) ,
        @sNextSurveyDue Date ,
        @sRiskCategory varchar(510) ,
        @sDocURL varchar(MAX) ,
        @sDocLinks varchar(MAX) ,
        @sVINCIRISKLevel varchar(510) ,
        @sRemedialActionWO varchar(510) ,
        @sRemedialActionDate date,
        @sComments varchar(MAX) ,
        @sRISKNUM varchar(510) ,
        @sRISKOWNER varchar(510) ,
        @sSurveyorsComments varchar(MAX) ,
        @sRecommendations varchar(510) ,
        @sStatusOfIssue int ,
        @sClientContract varchar(12) ,
        @sJPNUM varchar(12)
    ) AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
        DECLARE @sql NVARCHAR(max)
    
        SET @sql = N'
        INSERT INTO ' + QUOTENAME(LTRIM(RTRIM(@sTableName)))  + '
        (
            PMNUM
            , UPRN
            , VFMDISPLINE
            , VFMDISPLINEELEMENT
            , WorkOrder
            , RiskCategory
            , DocURL
            , DocLinks
            , VINCIRISKLevel
            , RemedialActionWO
            , Comments
            , RISKNUM
            , RISKOWNER
            , SurveyorsComments
            , Recommendation
            , StatusOfIssue
            , ClientContract
            , JPNUM
            , RemedialActionDate
            , SurveyDate
            , NextSurveyDate  
        )
        VALUES
        (
            @sPMNUM
            , @sUPRN
            , @sVFMDISCIPLINE
            , @sVFMDISCIPLINEELEMENT
            , @sWorkOrder
            , @sRiskCategory
            , @sDocURL
            , @sDocLinks
            , @sVINCIRISKLevel
            , @sRemedialActionWO
            , @sComments
            , @sRISKNUM
            , @sRISKOWNER
            , @sSurveyorsComments
            , @sRecommendations
            , @sStatusOfIssue
            , @sClientContract
            , @sJPNUM
            , @sRemedialActionDate
            , @sSurveyDate
            , @sNextSurveyDue
        )'
    
        EXEC sp_executesql @sql
            , N'@sPMNUM varchar(8)
                , @sUPRN varchar(510)
                , @sVFMDISCIPLINE varchar(4)
                , @sVFMDISCIPLINEELEMENT varchar(510)
                , @sWorkOrder varchar(510)
                , @sRiskCategory varchar(510)
                , @sDocURL varchar(MAX)
                , @sDocLinks varchar(MAX)
                , @sVINCIRISKLevel varchar(510)
                , @sRemedialActionWO varchar(510)
                , @sComments varchar(MAX)
                , @sRISKNUM varchar(510)
                , @sRISKOWNER varchar(510)
                , @sSurveyorsComments varchar(MAX)
                , @sRecommendations varchar(510)
                , @sStatusOfIssue int
                , @sClientContract varchar(12)
                , @sJPNUM varchar(12)
                , @sRemedialActionDate varchar(10)
                , @sSurveyDate varchar(10)
                , @sNextSurveyDue varchar(10)'
            , @sPMNUM = @sPMNUM
            , @sUPRN = @sUPRN
            , @sVFMDISCIPLINE = @sVFMDISCIPLINE
            , @sVFMDISCIPLINEELEMENT = @sVFMDISCIPLINEELEMENT
            , @sWorkOrder = @sWorkOrder
            , @sRiskCategory = @sRiskCategory
            , @sDocURL = @sDocURL
            , @sDocLinks = @sDocLinks
            , @sVINCIRISKLevel = @sVINCIRISKLevel
            , @sRemedialActionWO = @sRemedialActionWO
            , @sComments = @sComments
            , @sRISKNUM = @sRISKNUM
            , @sRISKOWNER = @sRISKOWNER
            , @sSurveyorsComments = @sSurveyorsComments
            , @sRecommendations = @sRecommendations
            , @sStatusOfIssue = @sStatusOfIssue
            , @sClientContract = @sClientContract
            , @sJPNUM = @sJPNUM
            , @sRemedialActionDate = @sRemedialActionDate
            , @sSurveyDate = @sSurveyDate
            , @sNextSurveyDue = @sNextSurveyDue     
    END;    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 2013-12-16
      • 1970-01-01
      • 2018-08-14
      • 2011-03-11
      • 2014-02-16
      • 2017-01-11
      相关资源
      最近更新 更多