我在 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 个参数,然后按“确定”,然后收到错误。
我一定错过了一些明显的东西,如果是这样,我提前道歉,但这是我第一次尝试在存储过程中使用动态列名,我很感激任何帮助!
感谢您的有用建议 - 我已经学到了很多东西:) 解决方案是声明一个变量字符串来包含整个查询,从而允许灵活使用传递的参数:
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