我想将Coldfusion 10中的学年列表传递给SQL Server 2008 R2上的存储过程。我在MSSQL中创建了一个自定义类型:
CREATE TYPE YearListType AS Table (years VARCHAR(10))
然后我的存储过程在我的存储过程中声明了这一点:
CREATE PROCEDURE [getCounts]
@years YearListType readonly
....
SELECT .......
WHERE school_year IN (SELECT * FROM @years)
现在在我的Coldfusion中,我用这种方式调用存储过程:
<cfstoredproc procedure="[getCounts]" datasource="...">
<cfprocparam cfsqltype="cf_sql_varchar" value="#yrlist#">
....
</cfstoredproc>
变量yrlist是逗号分隔列表。示例值如下所示:
"2001-2002,2002-2003,2003-2004"
当我执行时,我收到CF错误:
Operand type clash: varchar is incompatible with YearListType
我理解错误,但我不知道如何通过列表。我尝试向cfprocparam添加list =“yes”,但是我得到一个错误,说list参数与cfprocparam不兼容。据我所知,没有cf_sql_list类型,有吗?
如何将值列表传递给存储过程?我是否应该使用自定义SQL数据类型?
答案 0 :(得分:1)
ColdFusion没有&#34;列表&#34; <cfprocparam>
的属性,但它适用于<cfqueryparam>
。因此,您可以尝试使用sql语句调用存储过程,就像在SQL Server Management Studio中一样,并使用<cfqueryparam>
来包装参数。
这仍然不能解决ColdFusion不能(也不能)理解SQL Server自定义数据类型的问题。如果以编程方式而不是从用户输入生成年份列表(或者在使用之前清理用户输入),则可以省略cfsqltype
中的<cfqueryparam>
属性。
答案 1 :(得分:1)
我以前做过这件事。首先需要创建一个函数来拆分列表,然后在SQL中调用它。 FTR:我没有创造这个,我几年前通过谷歌发现了它。如果我有原始的源链接,我会参考那些野兔。我确定Google还有它们。只需搜索&#34; T-SQL fnSplit&#34;。
SELECT blah FROM foo WHERE bar IN (fnSplit(@valueList, ','))
这是您需要创建的功能。
USE [DBNAME]
GO
/****** Object: UserDefinedFunction [dbo].[fnSplit] Script Date: 09/06/2011 19:08:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fnSplit](
@sInputList VARCHAR(8000) -- List of delimited items
, @sDelimiter VARCHAR(8000) = ',' -- delimiter that separates items
) RETURNS @List TABLE (item VARCHAR(8000))
BEGIN
DECLARE @sItem VARCHAR(8000)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
BEGIN
SELECT
@sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))),
@sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))
IF LEN(@sItem) > 0
INSERT INTO @List SELECT @sItem
END
IF LEN(@sInputList) > 0
INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END
GO