2012-02-02 93 views
0

我正在写查询字符串直接放入存储区的通用函数。该算法非常基本 - 通过查询键循环,将它们用作参数名称,同时将该值用作参数值。因此,它看起来就像是这样的:有没有办法检查参数是否在存储过程中?

ArrayList pars = new ArrayList(); 
SqlParameter p; 
int tryInt; 
for (int i = 0; i < req.QueryString.Count; i++) 
{ 
    key = req.QueryString.AllKeys[i]; 

    if (int.TryParse(req[key], out tryInt)) 
    { 
     p = new SqlParameter("@" + key, SqlDbType.Int); 
     p.Value = tryInt; 
     pars.Add(p); 
    } 
} 

这工作得很好,到目前为止,除了当然的所有查询键必须为存储过程的参数相匹配,如果他们不,我得到一个SQL例外又说什么

@someParameter is not a parameter for procedure some_sproc 

但我需要能够传递查询字符串中的变量不会传递到存储过程,所以我需要一种方法来“忽略”它们。

有没有办法来测试一个给定的存储过程是否需要某个参数?所以,我可以沿着这些路线

if (paramExists("@" + key, "some_sproc") && int.TryParse(req[key], out tryInt)) 
{ 
    p = new SqlParameter("@" + key, SqlDbType.Int); 
    p.Value = tryInt; 
    pars.Add(p); 
} 
+0

虽然我得到了我所需要的答案,我意识到我不想再拍DB调用。相反,我现在做的是,任何查询变量,我想作为一个参数传递给我在开始时使用@符号的名称。因此,例如像这样的查询file.aspx?sproc=somesproc&@par1=param1&par2=param2将通过@ par1 sproc但不是par2 – ilia 2012-02-02 19:35:15

回答

3

您可以询问ANSI information_schema.parameters观点做一些事情,这将返回所有参数与他们的位置

SELECT parameter_name, ordinal_position FROM INFORMATION_SCHEMA.parameters 
WHERE SPECIFIC_NAME = 'some_sproc' 
+0

谢谢。这很有效,但我并没有为创建另一个数据库调用这个想法而疯狂,所以在想了一下之后,我想出了一个替代解决方案。我已经向我的帖子添加了评论的详细信息。 – ilia 2012-02-02 19:35:44

0

大多数数据块存储“元数据”,如结构可访问的系统表/视图中的存储过程。如果你使用MSS,我会查看sys.procedures和sys.parameters;加入这两个视图并按过程名称筛选。

4

您可以使用SqlCommandBuilder获得SP参数:

using (SqlConnection sqlConn = new SqlConnection(yourConnStr)) 
using (SqlCommand sqlCmd = new SqlCommand(yourProcedureName, sqlConn)) 
{ 
    sqlConn.Open(); 
    sqlCmd.CommandType = CommandType.StoredProcedure; 
    SqlCommandBuilder.DeriveParameters(sqlCmd); 
    // now you can check parameters in sqlCmd.Parameters 
} 

更多细节here

+0

当你说*现在你可以检查参数*你是什么意思?我该如何去做呢? – 2016-04-15 16:30:41

+1

@TotZam for(int i = 0; i Tomek 2016-04-19 12:48:04

相关问题