与storedprocedure有关的错误

时间:2009-04-15 11:35:09

标签: sql-server sql-server-2005

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[rptGGM]
(
    @FromDate datetime,
    @ToDate datetime,
    @PartyName varchar(50),
    @Type int
)

As
DECLARE @WhrStr VarChar(500)

SET @WhrStr = 
    CASE @Type
    WHEN 1 THEN
        ' And E.ATAAir between '+ @FromDate +' And '+@ToDate

    WHEN 2 THEN
        ' And D.ATASea between '+ @FromDate+ ' And '+@ToDate
    END
exec
(
'SELECT 
         A.FileNumber As [File No],
         S.POString As [PO Numbers],
         G.PartyName As [Exporter Name],
         C.CargoDesc As [Cargo Description],
         Dbo.ActualDate(A.ETA) As ETA,
         Dbo.ActualDate(IsNull(E.ATAAir, D.ATASea)) As ATA,
        S.SIString As [Supplier Invoices],
D.VesselName As [Vessel Name],
      D.VoyageNo As [Voyage No],
        dbo.PackCntDetails(A.FileID) As [Pk/Cnt Details]

FROM
    FileMain A

LEFT JOIN SIPOString S ON S.FileID=A.FileID
LEFT JOIN Party G ON G.PartyID = A.ExporterID
INNER JOIN Cargo C ON C.FileID = A.FileID
LEFT JOIN FileSea D ON D.FileID = A.FileID
LEFT JOIN FileAir E ON E.FileID = A.FileID

WHERE   
     G.PartyName='+@PartyName +' '+@WhrStr


)

执行上述程序时会出现以下错误 Msg 241,Level 16,State 1,Procedure rptGGM,Line 12 从字符串转换datetime时转换失败。 任何人都可以帮忙解决错误。

4 个答案:

答案 0 :(得分:2)

如果没有EXEC,这将是一个简单的查询。你为什么把所有这些包装在EXEC中?

答案 1 :(得分:1)

使用动态SQL是非常糟糕的做法,因为它不仅可能因转换问题和数据长度而失败,而且还允许SQL注入。

使用这样的正确查询:

SELECT 
         A.FileNumber As [File No],
         S.POString As [PO Numbers],
         G.PartyName As [Exporter Name],
         C.CargoDesc As [Cargo Description],
         Dbo.ActualDate(A.ETA) As ETA,
         Dbo.ActualDate(IsNull(E.ATAAir, D.ATASea)) As ATA,
        S.SIString As [Supplier Invoices],
D.VesselName As [Vessel Name],
      D.VoyageNo As [Voyage No],
        dbo.PackCntDetails(A.FileID) As [Pk/Cnt Details]

FROM
    FileMain A

LEFT JOIN SIPOString S ON S.FileID=A.FileID
LEFT JOIN Party G ON G.PartyID = A.ExporterID
INNER JOIN Cargo C ON C.FileID = A.FileID
LEFT JOIN FileSea D ON D.FileID = A.FileID
LEFT JOIN FileAir E ON E.FileID = A.FileID

WHERE   
     G.PartyName=@PartyName AND
     (
           ((@Type = 1) And (E.ATAAir Between @FromDate And @ToDate))
     Or
           ((@Type = 2) And (E.ATASea Between @FromDate And @ToDate))
     )

答案 2 :(得分:0)

您必须引用日期时间值

...
WHEN 1 THEN
    ' And E.ATAAir between '''+ CAST(@FromDate AS varchar(30)) +''' And '''+CAST(@ToDate AS varchar(30)) + ''''

WHEN 2 THEN
    ' And D.ATASea between '''+ CAST(@FromDate AS varchar(30))+ ' And '''+CAST(@ToDate AS varchar(30)) + ''''
END
...

稍后您也会在@partyname附近发生错误:

...
WHERE   
     G.PartyName='''+@PartyName +''' '+@WhrStr

编辑:添加了CAST!

答案 3 :(得分:0)

在构造@WhrStr时,您需要从datetime到varchar进行显式转换。以下应该有效:

CAST(@FromDate as varchar)