You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

存储过程INSERT执行报错:‘=’附近语法不正确

排查存储过程调用的语法错误原因

咱们来一步步拆解这个问题,理清楚哪里出了问题:

先看你的存储过程和调用语句

你创建的SP_v2存储过程代码如下:

ALTER PROCEDURE [dbo].[SP_v2] 
    @CashCountBatchNo INT, 
    @CashierID VARCHAR(10), 
    @Remarks VARCHAR(50), 
    @CashCount NVARCHAR(1000), 
    @ADJ NVARCHAR(1000) = '', 
    @CutOff VARCHAR(8) = '' 
AS 
SET NOCOUNT ON 
DECLARE @tbl TABLE(DENOMINATION MONEY, [COUNT] INT) 
DECLARE @tblADJ TABLE(Description VARCHAR(300), Amount MONEY) 
DECLARE @Totals TABLE(CC MONEY, CH MONEY, CASHTOCOLLECT MONEY) 

SET @CashCount = REPLACE(@CashCount, '_S_', ' Select ') 
SET @CashCount = REPLACE(@CashCount, '_;', ' union all ') 
SET @CashCount = SUBSTRING(@CashCount, 0, LEN(@CashCount) - 8) 

INSERT INTO @tbl(DENOMINATION, [COUNT]) 
EXEC sp_executesql @CashCount 

SELECT * FROM @tbl 
RETURN 

调用时使用的语句:

UERMHIMS..Usp_Cashier_SaveCashCount_v2 '', '', '', 'DENOMINATION=1000, COUNT=1 union select DENOMINATION=500, COUNT=1', '', ''

抛出的错误信息:

Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '='.

错误根源分析

问题出在动态SQL的构造逻辑上,咱们一步步追踪@CashCount的变化:

  1. 你传入的@CashCount字符串里既没有_S_也没有_;,所以存储过程里的前两次REPLACE操作完全没起作用,字符串保持原样。
  2. 接下来的SUBSTRING会截掉字符串末尾8个字符,原字符串末尾是, COUNT=1,截完后变成'DENOMINATION=1000, COUNT=1 union select DENOMINATION=500'——但这不是核心问题,核心是这个字符串本身就不是合法的SQL语句!

SQL中构造行数据不能直接写DENOMINATION=1000, COUNT=1,这种写法会让SQL解析器误以为DENOMINATION是变量或列名,遇到=时就会触发语法错误。正确的写法应该是SELECT 1000 AS DENOMINATION, 1 AS COUNT或者使用VALUES子句。

另外,从存储过程的REPLACE逻辑来看,它似乎期望你传入带特殊标记的字符串(比如'_S_ DENOMINATION=1000, COUNT=1 _; _S_ DENOMINATION=500, COUNT=1'),替换后会生成' Select DENOMINATION=1000, COUNT=1 union all Select DENOMINATION=500, COUNT=1'——但就算是这样,DENOMINATION=1000的写法依然不合法,还是会报错。

解决办法

给你两个可行的调整方向:

方向1:直接修正传入的参数格式

把@CashCount改成合法的SELECT语句片段,比如:

UERMHIMS..Usp_Cashier_SaveCashCount_v2 '', '', '', 'SELECT 1000 AS DENOMINATION, 1 AS COUNT union select 500 AS DENOMINATION, 1 AS COUNT', '', ''

同时记得删除存储过程里的SUBSTRING(@CashCount, 0, LEN(@CashCount) - 8)语句——这个逻辑是针对带_;标记的字符串设计的,现在参数格式变了,就不需要了。

方向2:调整存储过程的动态SQL生成逻辑

如果你想保留DENOMINATION=xxx, COUNT=xxx的简洁传入格式,可以修改存储过程里的替换逻辑,把这种格式转换成合法的SQL:

-- 将传入的片段转换为合法的SELECT语句
SET @CashCount = REPLACE(@CashCount, 'DENOMINATION=', 'SELECT ')
SET @CashCount = REPLACE(@CashCount, ', COUNT=', ' AS DENOMINATION, ')
SET @CashCount = REPLACE(@CashCount, ' union select ', ' AS COUNT union select ')
SET @CashCount = @CashCount + ' AS COUNT'

这个逻辑可以根据你实际的传入格式微调,确保最终生成的SQL语法合法。

最后提醒一句:当前存储过程存在SQL注入风险,因为它直接执行用户传入的字符串。如果是生产环境使用,建议要么对传入内容做严格校验,要么改用参数化动态SQL,避免安全隐患。


内容的提问来源于stack exchange,提问作者Alphatrix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:12:10