我有这个存储过程,它在VB.Net系统上执行。
CREATE OR ALTER PROCEDURE EsRl230
@EMPCod NVARCHAR(MAX),
@SGPId NVARCHAR(MAX),
@MAPId NVARCHAR(MAX),
@DtNaoVendido NVARCHAR(MAX),
@DtCadastro NVARCHAR(MAX)
AS
DECLARE @sql NVARCHAR(MAX)
SET @sql =
'SELECT ' +
'EMPSigla, ' +
'GRPCod, ' +
'GRPDesc, ' +
'SGPCod, ' +
'SGPDesc, ' +
'MAPDesc, ' +
'PROCod, ' +
'PROCodFab, ' +
'PRODesc = SUBSTRING(PRODesc,1,50), ' +
'PROAplic = SUBSTRING(PROAplic,1,100), ' +
'PREQtEst, ' +
'PREPrVd, ' +
'PRECstRp, ' +
'COSDtFec, ' +
'CNEDtLib ' +
'FROM ' +
'EsPRE (NoLock) ' +
'JOIN GnEMP (NoLock) ON EsPRE.EMPCod = GnEMP.EMPCod ' +
'JOIN EsINE (NoLock) ON EsPRE.PREid = EsINE.PREid ' +
'JOIN EsCNE (NoLock) ON EsINE.CNEId = EsCNE.CNEId ' +
'JOIN EsPRO (NoLock) ON EsPRE.PROId = EsPRO.PROId ' +
'JOIN EsSGP (NoLock) ON EsPRO.SGPId = EsSGP.SGPId ' +
'JOIN EsGRP (NoLock) ON EsSGP.GRPId = EsGRP.GRPId ' +
'LEFT JOIN EsMAP (NoLock) ON EsPRO.MAPId = EsMAP.MAPId ' +
'JOIN SeCOS (NoLock) ON SeCOS.EMPCod = GnEMP.EMPCod ' +
'JOIN SeCRQ (NoLock) ON SeCOS.COSid = SeCRQ.COSid ' +
'WHERE ' +
'EsPRE.EMPCod IN (' + @EMPCod + ') '
IF @SGPId IS NOT NULL
BEGIN
SET @sql = @sql + 'AND SGPId IN ' + @SGPId
END
IF @MAPId IS NOT NULL
BEGIN
SET @sql = @sql + 'AND MAPId IN (' + @MAPId + ') '
END
IF @DtNaoVendido IS NOT NULL
BEGIN
SET @sql = @sql + 'AND COSDtFec >= ' + @DtNaoVendido
END
IF @DtCadastro IS NOT NULL
BEGIN
SET @sql = @sql + ' AND CNEDtLib <= ' + @DtCadastro
END
EXEC (@sql)
GO
以这种方式执行:
execute EsRl230 '297', NULL, NULL, '02/04/2018' ,'23/04/2018'
它返回以下错误:
&#34;操作数类型冲突:datetime2与int&#34;
不兼容
有人可以帮助我吗?
答案 0 :(得分:0)
我无法解决这个问题。离开他们的查询/ SP对SQL注入开放的人是我的一个巨大的宠儿。在2018年,它不应该是人们对自己开放的东西。令我感到害怕的是,人们仍在使用字符串连接等不良实践在其应用程序中创建动态SQL或内联语句。
我必须在某些地方猜测,并假设你的SQL Server版本;代码中有关于我猜测/假设的原因或内容的评论。我还删除了那些肮脏的 NOLOCK
提示,因为您没有充分说明为什么要使用它(因此我只能假设因为错误的原因你正在使用它,正如许多人似乎所做的那样)。我强烈建议您查看此内容并了解我为什么按照我的方式完成此操作。我还建议您阅读SQL注入。很明显,你不明白它是什么,因为如果你理解了它的所有含义,你就不会写出如你所知的那样的查询:
ALTER PROCEDURE EsRl230 @EMPCod NVARCHAR(MAX),
@SGPId NVARCHAR(MAX),
@MAPId NVARCHAR(MAX),
@DtNaoVendido date, --Guessed data type
@DtCadastro date --Guessed data type
AS
DECLARE @sql NVARCHAR(MAX);
DECLARE @params nvarchar(MAX);
SET @sql =
N'SELECT EMPSigla,' + NCHAR(10) +
N' GRPCod,' + NCHAR(10) +
N' GRPDesc,' + NCHAR(10) +
N' SGPCod,' + NCHAR(10) +
N' SGPDesc,' + NCHAR(10) +
N' MAPDesc,' + NCHAR(10) +
N' PROCod,' + NCHAR(10) +
N' PROCodFab,' + NCHAR(10) +
N' PRODesc = SUBSTRING(PRODesc,1,50), ' + NCHAR(10) +
N' PROAplic = SUBSTRING(PROAplic,1,100), ' + NCHAR(10) +
N' PREQtEst,' + NCHAR(10) +
N' PREPrVd,' + NCHAR(10) +
N' PRECstRp,' + NCHAR(10) +
N' COSDtFec,' + NCHAR(10) +
N' CNEDtLib' + NCHAR(10) +
N'FROM EsPRE ' + NCHAR(10) + --Removed Nolock. Why is it there?
N' JOIN GnEMP ON EsPRE.EMPCod = GnEMP.EMPCod ' + NCHAR(10) + --Removed Nolock. Why was it there?
N' JOIN EsINE ON EsPRE.PREid = EsINE.PREid ' + NCHAR(10) + --Removed Nolock. Why was it there?
N' JOIN EsCNE ON EsINE.CNEId = EsCNE.CNEId ' + NCHAR(10) + --Removed Nolock. Why was it there?
N' JOIN EsPRO ON EsPRE.PROId = EsPRO.PROId ' + NCHAR(10) + --Removed Nolock. Why was it there?
N' JOIN EsSGP ON EsPRO.SGPId = EsSGP.SGPId ' + NCHAR(10) + --Removed Nolock. Why was it there?
N' JOIN EsGRP ON EsSGP.GRPId = EsGRP.GRPId ' + NCHAR(10) + --Removed Nolock. Why was it there?
N' LEFT JOIN EsMAP ON EsPRO.MAPId = EsMAP.MAPId ' + NCHAR(10) + --Removed Nolock. Why was it there?
N' JOIN SeCOS ON SeCOS.EMPCod = GnEMP.EMPCod ' + NCHAR(10) + --Removed Nolock. Why was it there?
N' JOIN SeCRQ ON SeCOS.COSid = SeCRQ.COSid' + NCHAR(10) + --Removed Nolock. Why was it there?
N'WHERE EsPRE.EMPCod IN (SELECT SS.[value]' + NCHAR(10) + --Removed Nolock. Why was it there?
N' FROM STRING_SPLIT(@dEmpCod,'','') SS)'; --Guessed you're using SQL Server 2016+
IF @SGPId IS NOT NULL
BEGIN
SET @sql = @sql + NCHAR(10) + N' AND SGPId IN @dSGPId';
END
IF @MAPId IS NOT NULL
BEGIN
SET @sql = @sql + NCHAR(10) + N' AND MAPId IN (SELECT SS.[value]' + NCHAR(10) +
N' FROM STRING_SPLIT(@dMAPId,'','') SS)'; --Guessed you're using SQL Server 2016+
END
IF @DtNaoVendido IS NOT NULL
BEGIN
SET @sql = @sql + NCHAR(10) + N' AND COSDtFec >= @dDtNaoVendido';
END
IF @DtCadastro IS NOT NULL
BEGIN
SET @sql = @sql + NCHAR(10) + N' AND CNEDtLib <= @dDtCadastro';
END
SET @sql = @sql + N';';
PRINT @SQL; --Your best friend
SET @params = N'@dEmpCod nvarchar(MAX), @dSGPId nvarchar(MAX), @dMAPId nvarchar(MAX), @dDtNaoVendido date, @dDtCadastro date'
EXEC sp_executesql @sql, @params, @dEmpCod = @EMPCod, @dSGPId = @SGPId, @dMAPId = @MAPId, @dDtNaoVendido = @DtNaoVendido, @dDtCadastro = @DtCadastro;
GO
另外,请在未经测试中注意此SQL。使用你最好的朋友来调试它,如果它没有工作。
答案 1 :(得分:-1)
除了注释中提到的大量错误之外,这里是此查询的WHERE子句。检查日期的使用方式。
最好是PRINT动态SQL并在直接通过存储过程执行它之前单独运行它。
WHERE EsPRE.EMPCod IN (297) AND COSDtFec >= 02 / 04 / 2018 AND CNEDtLib <= 23 / 04 / 2018
您可以尝试以下操作:
create or alter PROCEDURE EsRl230
@EMPCod NVARCHAR(MAX),
@SGPId NVARCHAR(MAX),
@MAPId NVARCHAR(MAX),
@DtNaoVendido NVARCHAR(MAX),
@DtCadastro NVARCHAR(MAX)
AS
DECLARE @sql NVARCHAR(MAX)
SET @sql =
'SELECT ' +
'EMPSigla, ' +
'GRPCod, ' +
'GRPDesc, ' +
'SGPCod, ' +
'SGPDesc, ' +
'MAPDesc, ' +
'PROCod, ' +
'PROCodFab, ' +
'PRODesc = SUBSTRING(PRODesc,1,50), ' +
'PROAplic = SUBSTRING(PROAplic,1,100), ' +
'PREQtEst, ' +
'PREPrVd, ' +
'PRECstRp, ' +
'COSDtFec, ' +
'CNEDtLib ' +
'FROM ' +
'EsPRE (NoLock) ' +
'JOIN GnEMP (NoLock) ON EsPRE.EMPCod = GnEMP.EMPCod ' +
'JOIN EsINE (NoLock) ON EsPRE.PREid = EsINE.PREid ' +
'JOIN EsCNE (NoLock) ON EsINE.CNEId = EsCNE.CNEId ' +
'JOIN EsPRO (NoLock) ON EsPRE.PROId = EsPRO.PROId ' +
'JOIN EsSGP (NoLock) ON EsPRO.SGPId = EsSGP.SGPId ' +
'JOIN EsGRP (NoLock) ON EsSGP.GRPId = EsGRP.GRPId ' +
'LEFT JOIN EsMAP (NoLock) ON EsPRO.MAPId = EsMAP.MAPId ' +
'JOIN SeCOS (NoLock) ON SeCOS.EMPCod = GnEMP.EMPCod ' +
'JOIN SeCRQ (NoLock) ON SeCOS.COSid = SeCRQ.COSid ' +
'WHERE ' +
'EsPRE.EMPCod IN (' + @EMPCod + ') '
IF @SGPId IS NOT NULL
BEGIN
SET @sql = @sql + 'AND SGPId IN ' + @SGPId
END
IF @MAPId IS NOT NULL
BEGIN
SET @sql = @sql + 'AND MAPId IN (' + @MAPId + ') '
END
IF @DtNaoVendido IS NOT NULL
BEGIN
SET @sql = @sql + 'AND COSDtFec >= ''' + @DtNaoVendido + ''''
END
IF @DtCadastro IS NOT NULL
BEGIN
SET @sql = @sql + ' AND CNEDtLib <= ''' + @DtCadastro + ''''
END
--EXEC (@sql)
PRINT @sql
GO