将列表传递给SQL自定义类型

时间:2014-08-14 15:40:26

标签: sql sql-server stored-procedures coldfusion coldfusion-10

我想将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数据类型?

我读过thisthis,但我无法弄清楚它的Coldfusion方面。

2 个答案:

答案 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