尝试在 SQL Server 存储过程中使用动态列时出错

问题描述 投票:0回答:1

我在 Stack Overflow 上看到了几篇文章,描述了如何在 SQL Server 存储过程中使用动态列,但我的尝试导致出现有关我尝试使用的动态列名称的错误消息。

消息 245,级别 16,状态 1,过程 sp_FetchBrandImagesNoCatID,第 21 行 [批量开始行 2]
将 varchar 值“share_on_macy”转换为数据类型 int 时转换失败。

当我不尝试引用动态列名时,存储过程工作正常,只有当我添加使用动态列名时才会出现错误(我使用的是 SQL Server 2014)。

这是存储过程:尝试使用传递给存储过程的列名

@APPEARONLANGUAGE
@SHAREONCOLUMNNAME
时会发生错误。两列在表中均定义为 INT:

USE [test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[sp_FetchBrandImagesNoCatID] 
    @BRANDID varchar(10),
    @STORE varchar(30),
    @APPEARONLANGUAGE varchar(100),
    @SHAREONCOLUMNNAME varchar(100),
    @RECS int
AS
BEGIN
    SET NOCOUNT ON;

    SELECT TOP (@RECS) * 
    FROM  
        (SELECT 
             *, 
             ROW_NUMBER() OVER (ORDER BY adminsort1 DESC, adminsort2 DESC, randomsort ASC) AS rownum 
         FROM  
             (SELECT DISTINCT TOP 100 PERCENT  
                  retail_images.id, retail_images.guid,
                  retail_images.folder, retail_images.filename, 
                  CAST(retail_images.captionenglish AS nvarchar(500)) AS caption, 
                  CAST(retail_images.source AS nvarchar(500)) AS source,  
                  b.folder AS bfolder, b.filename AS bfilename,
                  retail_customers.displayname,  
                  (SELECT Count(*) 
                   FROM retail_image_likes 
                   WHERE retail_images.id = retail_image_likes.imageid) AS LikeCount,
                  retail_customers.id AS profileid,
                  retail_images.videoid, retail_images.videopadding,
                  retail_images.duration, retail_images.filename_cloud,
                  retail_images.bucket_cloud, retail_images.store,
                  retail_images.cloudflareid, b.cloudflareid AS bcloudflareid, 
                  retail_images.cloudflareid_chinese, 
                  retail_images.cloudflareid_taiwan,
                  retail_images.cloudflareid_spanish,  
                  SUBSTRING(CAST(retail_images.guid AS varchar(50)), 28, 1) AS randomsort,
                  retail_images.admin_set_priority AS adminsort1,  
                  retail_images.prioritypoints AS adminsort2  
              FROM 
                  retail_images  
              LEFT OUTER JOIN 
                  retail_images b ON (retail_images.customerid = b.customerid 
                                      AND retail_images.customerid <> 0  
                                      AND b.filetype = N'M' 
                                      AND b.approved = 1)  
              LEFT OUTER JOIN 
                  retail_customers ON (retail_images.customerid = retail_customers.id)  
              LEFT OUTER JOIN  
                  Products ON (Products.productid = retail_images.productid1 
                               OR Products.productid = retail_images.productid2 
                               OR Products.productid = retail_images.productid3 
                               OR Products.productid = retail_images.productid4 
                               OR Products.productid = retail_images.productid5 
                               OR Products.productid = retail_images.productid6 
                               OR Products.productid = retail_images.productid7 
                               OR Products.productid = retail_images.productid8)   
                            AND Products.brandid = @BRANDID 
              INNER JOIN 
                  Brand ON (retail_images.brandid = Brand.id 
                            OR Products.brandid = Brand.id)
                        AND Brand.id = @BRANDID 
              WHERE  
                  (retail_images.approved = 1 
                   AND retail_images.hidden = 0) 
                  AND (@APPEARONLANGUAGE = 1)   
                  AND ((retail_images.store = '@STORE') OR (@SHAREONCOLUMNNAME = 1))  
                  AND (retail_images.filetype = N'I')  
                  AND (retail_images.is_posting <> 1)  
                  AND retail_images.loginrequired = 0  
                  AND retail_images.is_subscription = 0  
              ORDER BY 
                  adminsort1 DESC, adminsort2 DESC, randomsort ASC) subqry) subqry2  
    ORDER BY  
        rownum
END

当我从 SQL Server Management Studio“执行存储过程”调用存储过程时,我在提供的对话框中提供了 5 个参数,然后按“确定”,然后收到错误。

我一定错过了一些明显的东西,如果是这样,我提前道歉,但这是我第一次尝试在存储过程中使用动态列名,我很感激任何帮助!

stored-procedures sql-server-2014 dynamic-columns
1个回答
0
投票

感谢您的有用建议 - 我已经学到了很多东西:) 解决方案是声明一个变量字符串来包含整个查询,从而允许灵活使用传递的参数:

USE [test_inventory]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[sp_FetchBrandImagesNoCatID] 
    @BRANDID varchar(10),
    @STORE varchar(30),
    @APPEARONLANGUAGE varchar(100),
    @SHAREONCOLUMNNAME varchar(100),
    @RECS varchar(6)
AS
BEGIN

DECLARE @SQL AS nvarchar(max)

SET NOCOUNT ON;

SET @SQL = N'
SELECT TOP ' + (@RECS) + N' * FROM  
(SELECT *, ROW_NUMBER() OVER (ORDER BY adminsort1 desc,adminsort2 desc,randomsort asc) as rownum 
FROM  (SELECT DISTINCT TOP 100 PERCENT retail_images.id,retail_images.guid,retail_images.folder,retail_images.filename, 
CAST(retail_images.captionenglish as nvarchar(500)) as caption, CAST(retail_images.source as nvarchar(500)) as source,  
b.folder as bfolder,b.filename as bfilename,retail_customers.displayname,  (SELECT Count(*) 

FROM retail_image_likes
 
WHERE retail_images.id = retail_image_likes.imageid) AS LikeCount ,retail_customers.id as profileid,
retail_images.videoid,retail_images.videopadding,retail_images.duration,retail_images.filename_cloud,
retail_images.bucket_cloud,retail_images.store,retail_images.cloudflareid,b.cloudflareid as bcloudflareid, 
retail_images.cloudflareid_chinese,retail_images.cloudflareid_taiwan,retail_images.cloudflareid_spanish,  
SUBSTRING(CAST(retail_images.guid as varchar(50)),28,1) as randomsort ,retail_images.admin_set_priority as adminsort1,  
retail_images.prioritypoints as adminsort2  

FROM retail_images  

LEFT OUTER JOIN retail_images b  ON ( retail_images.customerid = b.customerid AND retail_images.customerid<>0  AND  
b.filetype=N''M'' AND b.approved=1)
  
LEFT OUTER JOIN retail_customers ON (retail_images.customerid = retail_customers.id )
  
LEFT OUTER JOIN  Products ON   (Products.productid = retail_images.productid1 OR  
Products.productid = retail_images.productid2 OR  Products.productid = retail_images.productid3 OR  
Products.productid = retail_images.productid4 OR  Products.productid = retail_images.productid5 OR  
Products.productid = retail_images.productid6 OR  Products.productid = retail_images.productid7 OR  
Products.productid = retail_images.productid8)   AND Products.brandid = ' + @BRANDID + N'

INNER JOIN Brand ON (retail_images.brandid = Brand.id OR Products.brandid = Brand.id)AND Brand.id = ' + 
@BRANDID + N'

WHERE  (retail_images.approved=1 AND retail_images.hidden=0) 
AND (retail_images.appearon' + @APPEARONLANGUAGE + N'=1)   
AND ((retail_images.store = ''' + @STORE + N''') OR (retail_images.share_on_' + @SHAREONCOLUMNNAME + N'=1))  
AND (retail_images.filetype=N''I'')  AND 
( retail_images.is_posting <> 1 )  AND retail_images.loginrequired = 0  AND retail_images.is_subscription = 0  

ORDER BY adminsort1 desc,adminsort2 desc,randomsort asc ) subqry) subqry2  
ORDER BY rownum'

EXEC(@SQL)

END

© www.soinside.com 2019 - 2024. All rights reserved.