操作数类型冲突:datetime2与int不兼容

时间:2018-04-23 14:56:21

标签: sql sql-server

我有这个存储过程,它在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;

不兼容

有人可以帮助我吗?

2 个答案:

答案 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