【问题标题】:Pass List of Integers to Stored Procedure将整数列表传递给存储过程
【发布时间】:2015-05-07 18:29:30
【问题描述】:

这是我的存储过程:

ALTER PROCEDURE [dbo].[Dan] 
@numbers varchar(10)    
AS
BEGIN
SET NOCOUNT ON;
select @numbers numbers
END

在 SSMS 中,我可以像这样成功执行它:

exec dbo.Dan '1.2' 

在 ColdFusion 中,我可以使用以下两组命令中的任何一个成功执行它:

<cfstoredproc procedure="dbo.dan" datasource="ClinicalDataDev">
<cfprocparam cfsqltype="cf_sql_varchar" value="1,2"> 
<cfprocresult name="abc">
</cfstoredproc>

<cfquery name="abcd" datasource="ClinicalDataDev">
exec dbo.Dan <cfqueryparam cfsqltype="cf_sql_varchar" value='1,2' list="no">
</cfquery>

但是,我希望通过将值指定为整数列表来改进这一点。由于 cfprocparam 没有 list 属性,我想我仅限于 cfquery 方法。到目前为止,我的努力和成果是:

<cfqueryparam cfsqltype="cf_sql_integer" value='1' list="no">
executes successfully.  The purpose is to see if the procedure accepts an 
integer - it does.

<cfqueryparam cfsqltype="cf_sql_integer" value='1,2' list="no">
also executes sucessfully, but returns a value of 42006.  Probably not 
worth persuing.

<cfqueryparam cfsqltype="cf_sql_integer" value='1,2' list="yes">
throws an error for two many paramters.  
The same thing happens with cf_sql_varchar.

如前所述,我可以将列表作为字符串传递,但这似乎有点不合时宜。有没有办法将整数列表作为整数列表传递?

【问题讨论】:

  • 将它们作为 varchar 传递是一团糟。然后,您必须将它们解析回不好的整数。您可能想看看使用表值参数。 msdn.microsoft.com/en-us/library/bb510489.aspx
  • 如果您担心将它们解析为整数,您也可以使用 XML 并使用模式强制类型。虽然只是为了我的两分钱,但我一直将分隔列表与良好的拆分器功能结合使用。这似乎比 TVP 更不让人头疼。再次,恕我直言。
  • 我不知道coldfusion,但从sql的角度来看,表值参数是要走的路。
  • @Xedni 那里有很多可怕的拆分器,无论您如何对其进行切片,最好的方法是不要强制 sql 拆分值。话虽如此,有时可以,但作为一般规则,您应该避免传递分隔字符串。这是一篇关于拆分字符串的好文章。 sqlperformance.com/2012/07/t-sql-queries/split-strings
  • 考虑在 stackoverflow.com/questions/19213814/… 中概述的基于 XML 的方法。它也适用于存储过程。

标签: sql-server coldfusion


【解决方案1】:

正如其他评论者之前提到的,传递表值参数是可行的方法。这将要求您更改 SP 中的输入以获取表格输入,并且在您的查询中您可以这样做

<cfquery>
    CREATE TABLE @temp (usedID int)
    INSERT INTO @temp 
        (usedID)
        VALUES
        (1)
        ,(2)

    exec dbo.Dan @temp
</cfquery>

您可能必须更改将参数传递给 SP 的方式,但这是一般的想法。

【讨论】:

  • 到目前为止,我已经给了你一票。如果您想获得答案,请修复 cfquery 标记内的 sql server 语法。请参阅我的回答作为参考。
【解决方案2】:

rodmunera 的回答有正确的总体思路。这就是我最终让它工作的方法。

在 sql server 中,我是这样开始的:

CREATE  TYPE pt.IntegerTableType AS TABLE 
( integerIN int);
grant execute on type::pt.IntegerTableType to theAppropriateRole

然后我将存储过程更改为:

ALTER PROCEDURE [dbo].[Dan] 
@numbers pt.IntegerTableType readonly
AS
BEGIN
SET NOCOUNT ON;
select 1 record 
where 1 in (select integerIN from @numbers) 
END

Coldfusion 代码是这样的:

<cfset numbers = "1,2">
<cfquery name="abcd" datasource="ClinicalDataDev">
declare @dan as pt.IntegerTableType

insert into @dan
select null 
where 1 = 2
<cfloop list="#numbers#" index="number">
union
select <cfqueryparam cfsqltype="cf_sql_integer" value="#number#">
</cfloop>

exec dbo.Dan @dan
</cfquery>
<cfdump var="#abcd#">

【讨论】:

    猜你喜欢
    • 2012-09-01
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 2014-09-26
    • 1970-01-01
    相关资源
    最近更新 更多