Sql server 存储过程错误转换SQL Server

Sql server 存储过程错误转换SQL Server,sql-server,stored-procedures,pivot,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

我想编写一个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值时失败“从中选择tanggal、[54]、[11]、[56]、[53]、[40]、[21]、[12] 选择 cpo.tanggal, 阿萨尔总干事, cpo-ongkos-ms*CASTNULLIFdg.minyak-efektif,0为浮点数/NULLIFdg.tbs-diolah,0+pko-ongkos-ms*CASTNULLIFdg.inti-efektif,0为浮点数/NULLIFdg.tbs-diolah,0-447.6*CASTNULLIFdg.minyak-efektif,0为浮点数/NULLIFdg.tbs-diolah,0+CASTNULLIFdg.inti-efektif,0为浮点数/NULLIFdg.tbs-Tbu-minyak-diolah,0为浮点数/NULLIFdg.tbs_diolah,0+pko-ongkos_为*CASTNULLIFdg.inti_efktif,0为浮点数/NULLIFdg.tbs_diolah,0-447.6*CASTNULLIFdg.minyak_efktif,0为浮点数/NULLIFdg.tbs_diolah,0+CASTNULLIFdg.inti_efktif,0为浮点数/NULLIFdg.tbs_diolah,0为0*0.02 作为哈尔加·贝里·特布斯·贝西 从…起 cpopko cpo 在CONVERT datetime上将DAILY_GUU作为dg左连接,dg.tglolah,103=cpo.tanggal 左连接PNL_TR_HARGA_KOMODITI作为ko ON ko.tanggal=cpo.tanggal 哪里 年份cpo.tanggal>='到数据类型int


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

错误是由于将integer@tahun变量与字符串连接在一起。由于INT比varchart具有更高的优先级,字符串将隐式转换为INT,因此错误将被忽略。因此需要将@tahun显式转换为varchar

您还必须对查询中使用的变量进行重命名。但我更喜欢使用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 

该错误是由于将整型@tahun变量与字符串串联而导致的。由于INT比varchart具有更高的优先级,字符串将隐式转换为INT,因此错误将被忽略。因此需要将@tahun显式转换为varchar

您还必须对查询中使用的变量进行重命名。但我更喜欢使用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 

我已经将“@query”字符串中的所有参数强制转换为varchar,但没有结果。先生,我也需要在“@cols”中加入params吗?。execute和Sp_executesql thnks be4之间有什么区别sir@Jsnow-将参数值传递给静态查询,并检查其是否返回任何记录。SP_EXECUTESQL允许您将值传递给动态查询中的变量,它避免了SQL注入。您还可以从动态查询变量中获得结果。检查此处以了解更多信息此数据透视表基于上一个表中的值获取了动态列。从我学到的返回一些东西,我们可以使用函数,但要返回表值,我们必须预定义临时表及其列。我们如何在函数中创建一个临时表,其中它的列是基于查询结果动态的。事先谢谢,先生。我已经将“@query”字符串中的所有参数强制转换为varchar,但没有结果。先生,我也需要在“@cols”中加入params吗?。execute和Sp_executesql thnks be4之间有什么区别sir@Jsnow-将参数值传递给静态查询,并检查其是否返回任何记录。SP_EXECUTESQL允许您将值传递给动态查询中的变量,它避免了SQL注入。您还可以从动态查询变量中获得结果。检查此处以了解更多信息此数据透视表基于上一个表中的值获取了动态列。从我学到的返回一些东西,我们可以使用函数,但要返回表值,我们必须预定义临时表及其列。我们如何在函数中创建一个临时表,其中它的列是基于查询结果动态的。先谢谢你,先生。