存储过程错误转换SQL Server

时间:2016-12-02 02:04:03

标签: sql-server stored-procedures pivot

我想编写一个SQL Server存储过程来从此查询中检索透视结果

ALTER procedure [dbo].[sp_get_list_penerimaan_pks]
    (@tahun int,
     @bulan int,
     @pks int)
as  
begin
    SET NOCOUNT ON;

    declare @cols AS NVARCHAR(MAX); 
    declare @query  AS NVARCHAR(MAX);

    SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.asal) 
            FROM (
              SELECT
                cpo.tanggal,
                dg.asal,
                (((((cpo - ongkos_ms)* CAST(NULLIF(dg.minyak_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))) +((pko - ongkos_is)* CAST(NULLIF(dg.inti_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))))-(447.6 * ((CAST(NULLIF(dg.minyak_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0)))+(CAST(NULLIF(dg.inti_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0))))) )-(((((cpo - ongkos_ms)* CAST(NULLIF(dg.minyak_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))) +((pko - ongkos_is)* CAST(NULLIF(dg.inti_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))))-(447.6 * ((CAST(NULLIF(dg.minyak_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0)))+(CAST(NULLIF(dg.inti_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0)))))) * 0.02)) 
                as harga_beli_tbs_bersih
              FROM
                cpopko cpo
              LEFT JOIN DAILY_GUU AS dg ON CONVERT (datetime, dg.tglolah, 103) = cpo.tanggal
              LEFT JOIN PNL_TR_HARGA_KOMODITI AS ko ON ko.tanggal = cpo.tanggal
              WHERE
                YEAR (cpo.tanggal) >= @tahun and pks=@pks and month(cpo.tanggal)=@bulan
            ) c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

    set @query = 'SELECT tanggal, ' + @cols + ' from 
            (
                  SELECT
                  cpo.tanggal,
                  dg.asal,
                  (((((cpo - ongkos_ms)* CAST(NULLIF(dg.minyak_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))) +((pko - ongkos_is)* CAST(NULLIF(dg.inti_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))))-(447.6 * ((CAST(NULLIF(dg.minyak_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0)))+(CAST(NULLIF(dg.inti_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0))))) )-(((((cpo - ongkos_ms)* CAST(NULLIF(dg.minyak_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))) +((pko - ongkos_is)* CAST(NULLIF(dg.inti_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))))-(447.6 * ((CAST(NULLIF(dg.minyak_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0)))+(CAST(NULLIF(dg.inti_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0)))))) * 0.02)) 
                  as harga_beli_tbs_bersih
                FROM
                  cpopko cpo
                LEFT JOIN DAILY_GUU AS dg ON CONVERT (datetime, dg.tglolah, 103) = cpo.tanggal
                LEFT JOIN PNL_TR_HARGA_KOMODITI AS ko ON ko.tanggal = cpo.tanggal
                WHERE
                  YEAR (cpo.tanggal) >= '+@tahun +' and pks=@pks and month(cpo.tanggal)=@bulan
           ) x
            pivot 
            (
                 max(harga_beli_tbs_bersih)
                for asal in (' + @cols + ')
            ) p '

    execute(@query)
end

但是我得到了这个错误结果:

  

程序执行失败22018 - [SQL Server]转换nvarchar值时转换失败' SELECT tanggal,[54],[11],[56],[53],[40],[21], [12]来自                   (                         选择                         cpo.tanggal,                         dg.asal,                         ((((((cpo - ongkos_ms)* CAST(NULLIF(dg.minyak_efektif,0)as float)/(NULLIF(dg.tbs_diolah,0)))+((pko - ongkos_is)* CAST(NULLIF(dg.inti_efektif) ,0)as float)/(NULLIF(dg.tbs_diolah,0)))) - (447.6 *((CAST(NULLIF(dg.minyak_efektif,0)as float)/(NULLIF(dg.tbs_diolah,0))) +(CAST(NULLIF(dg.inti_efektif,0)as float)/(NULLIF(dg.tbs_diolah,0)))))) - (((((cpo - ongkos_ms)* CAST(NULLIF(dg.minyak_efektif,0) )as float)/(NULLIF(dg.tbs_diolah,0)))+((pko - ongkos_is)* CAST(NULLIF(dg.inti_efektif,0)as float)/(NULLIF(dg.tbs_diolah,0)))) - (447.6 *((CAST(NULLIF(dg.minyak_efektif,0)as float)/(NULLIF(dg.tbs_diolah,0)))+(CAST(NULLIF(dg.inti_efektif,0)as float)/(NULLIF( dg.tbs_diolah,0))))))* 0.02))                         as harga_beli_tbs_bersih                       从                         cpopko cpo                       LEFT JOIN DAILY_GUU AS dg ON CONVERT(datetime,dg.tglolah,103)= cpo.tanggal                       LEFT JOIN PNL_TR_HARGA_KOMODITI AS ko ON ko.tanggal = cpo.tanggal                       哪里                         年(cpo.tanggal)> ='数据类型int。

我对这个错误感到很困惑。我已经从谷歌做了一些研究,但仍然无法解决问题。希望你们能帮助我 - 提前谢谢。

1 个答案:

答案 0 :(得分:2)

错误是由于将整数@tahun变量与字符串连接起来的。由于INT优先级高于Varchar,因此字符串将隐式转换为INT,因此错误。因此,您需要将@tahun明确转换为varchar

YEAR (cpo.tanggal) >= '+cast(@tahun as varchar(50))+' 

此外,您还必须重命名以重命名查询中使用的变量。但我更愿意使用SP_EXECUTESQL将值传递给变量

SET @query = 'SELECT tanggal, ' + @cols
             + ' from 
            (
                  SELECT
                  cpo.tanggal,
                  dg.asal,
                  (((((cpo - ongkos_ms)* CAST(NULLIF(dg.minyak_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))) + ((pko - ongkos_is)* CAST(NULLIF(dg.inti_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))))-(447.6 * ((CAST(NULLIF(dg.minyak_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0)))+(CAST(NULLIF(dg.inti_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0))))) )-(((((cpo - ongkos_ms)* CAST(NULLIF(dg.minyak_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))) +((pko - ongkos_is)* CAST(NULLIF(dg.inti_efektif,0) as float) / (NULLIF(dg.tbs_diolah, 0))))-(447.6 * ((CAST(NULLIF(dg.minyak_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0)))+(CAST(NULLIF(dg.inti_efektif,0) as float)  / (NULLIF(dg.tbs_diolah, 0)))))) * 0.02)) 
                  as harga_beli_tbs_bersih
                FROM
                  cpopko cpo
                LEFT JOIN DAILY_GUU AS dg ON CONVERT (datetime, dg.tglolah, 103) = cpo.tanggal
                LEFT JOIN PNL_TR_HARGA_KOMODITI AS ko ON ko.tanggal = cpo.tanggal
                WHERE
                  YEAR (cpo.tanggal) >= @tahun  and pks=@pks and month(cpo.tanggal)=@bulan
           ) x
            pivot 
            (
                 max(harga_beli_tbs_bersih)
                for asal in (' + @cols
             + ')
            ) p '

EXEC Sp_executesql
  @query,
  N'@tahun int,@pks int,@bulan int',
  @tahun = @tahun,
  @pks = @pks,
  @bulan = @bulan