【问题标题】:How to call Parameterized Stored Procedure in C# (ASP.Net)?如何在 C# (ASP.Net) 中调用参数化存储过程?
【发布时间】:2017-09-29 12:14:40
【问题描述】:

我正在开发一个网络应用程序,我希望用户在文本框中输入一个字符串并单击搜索按钮;它将在整个数据库中搜索用户输入的字符串(即,它将在网格视图中显示数据库名称、模式名称、表名称、列名称和记录名称)。

我已经在 SQL 中编写了存储过程并成功执行,其中存储过程在数据库中搜索输入的字符串并将数据插入到名为 tempdb.dbo.result 的表中。

这是我在数据库中搜索字符串的存储过程:

Use tempdb
GO

Create Table Result
(
    [Sno] int identity(1,1),
    [Database Name] sysname,
    [Schema Name] sysname,
    [Table Name] sysname,
    [Column Name] sysname,
    [Record Name] varchar(Max)
)

USE TestDB2
GO

CREATE PROCEDURE Find_Record_Across_Tables_Proc
     @Database sysname,
     @Schema sysname,
     @Table sysname,
     @String VARCHAR(Max)
AS
    DECLARE @SqlString varchar(Max)
    DECLARE @Table_Schema sysname
    DECLARE @Table_Name sysname
    DECLARE @Column_Name sysname

    --Declare Cursor
    SET @SqlString = 'DECLARE String_cursor CURSOR FOR
    Select TABLE_SCHEMA, TABLE_NAME ,COLUMN_NAME from
    ' + @Database +'.INFORMATION_SCHEMA.COLUMNS
    Where DATA_TYPE IN (''text'',''ntext'',''varchar''
    ,''nvarchar'',''char'',''nchar'')'

    --Filter schema name
    IF @schema IS NOT NULL
    Begin
        SET @SqlString = @SqlString + ' And TABLE_SCHEMA=''' + @Schema + ''''
    End

    --Filter table name
    IF @table IS NOT NULL
    Begin
        SET @SqlString = @SqlString + ' And TABLE_NAME=''' + @table + ''''
    End

    Print @SqlString
    EXEC (@SqlString)

OPEN String_cursor

FETCH NEXT FROM String_cursor
INTO @Table_Schema, @Table_Name, @Column_Name

WHILE @@FETCH_STATUS = 0
BEGIN
SET @SqlString = 'IF EXISTS(SELECT ' + QUOTENAME(@Column_Name)
+ ' FROM ' + @Database + '.' + QUOTENAME(@Table_Schema)
+ '.' + QUOTENAME(@Table_Name)
+ ' WHERE ' + QUOTENAME(@Column_Name)
+ ' Like ''%' + @string + '%'')
Insert into tempdb.dbo.result
([Database Name],[Schema Name]
,[Table Name],[Column Name],[Record Name])
SELECT ''' + QUOTENAME(@Database) + ''','''
+ QUOTENAME(@Table_Schema) + ''','''
+ QUOTENAME(@Table_Name) + ''',''''
+ ''' + QUOTENAME(@Column_Name)
+ ''',' + QUOTENAME(@Column_Name)
+ ' FROM ' + @Database + '.'
+ QUOTENAME(@Table_Schema)
+ '.' + QUOTENAME(@Table_Name)
+ ' WHERE ' + QUOTENAME(@Column_Name)
+ ' Like ''%' + @string + '%'''
Print @SqlString
EXEC (@SqlString)

FETCH NEXT FROM String_cursor
INTO @Table_Schema, @Table_Name, @Column_Name

END
CLOSE String_cursor
DEALLOCATE String_cursor
GO

我已经通过这些命令成功地在 SQL 中执行了这个存储过程:

Use TestDB2
GO

EXEC Find_Record_Across_Tables_Proc
'TestDB2(My database name)', NULL, NULL ,'string to be searched'
GO

Select * from tempdb.dbo.result
GO 

现在,每当我从 Web 应用程序执行(调用)这个参数化存储过程时,编译器在调用存储过程时不会显示异常,但它只会运行 BindGrid() 中的选择查询。

这是我的代码:

public partial class WebForm1 : System.Web.UI.Page
{
     DataSet ds = new DataSet();
     SqlConnection con;

     protected void Page_Load(object sender, EventArgs e)
     {
     }

     protected void Button1_Click(object sender, EventArgs e)
     {
         String value = TextBox1.Text.ToString();

         con = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDbConn"].ConnectionString);
         con.Open(); 

         SqlCommand cmd = new SqlCommand("Find_Record_Across_Tables_Proc", con);
         cmd.CommandType = CommandType.StoredProcedure;

         cmd.Parameters.AddWithValue("@Database", "TestDB2");
         cmd.Parameters.AddWithValue("@Schema", "NULL");
         cmd.Parameters.AddWithValue("@Table", "NULL");
         cmd.Parameters.AddWithValue("@String", value);

         cmd.ExecuteNonQuery(); 
         con.Close();

         this.BindGrid();
     }

     private void BindGrid()
     {
         string constr = ConfigurationManager.ConnectionStrings["MyDbConn"].ConnectionString;

         using (SqlConnection con = new SqlConnection(constr))
         {
             using (SqlCommand cmd = new SqlCommand("Select * from tempdb.dbo.result"))
             {
                    using (SqlDataAdapter sda = new SqlDataAdapter())
                    {
                        cmd.Connection = con;
                        sda.SelectCommand = cmd;
                        using (DataTable dt = new DataTable())
                        {
                            sda.Fill(dt);
                            GridView1.DataSource = dt;
                            GridView1.DataBind();
                        }
                    }
                }
            }
        }
    }

【问题讨论】:

  • 你遇到了什么错误?
  • 它没有给我任何错误,也没有例外。但是在执行时它将成功执行 BindGrid() 并在网格视图中显示结果使用 (SqlCommand cmd = new SqlCommand("Select * from tempdb.dbo.result"))
  • 你能在他的数据库中插入数据吗?
  • 我在SP里面写了插入命令。每当我通过 SQL 执行它们时,它就会成功执行
  • 即tempdb.dbo.result 表成功显示输入字符串所在的数据库名称、架构名称、表名称、列名称和记录名称

标签: c# asp.net sql-server stored-procedures web-applications


【解决方案1】:

在您的button_Click 中为cmd.ExecuteNonQuery(); 分配一个int 值i

例如:

 int i =cmd.ExecuteNonQuery();
 if(i>0)
 {
     this.BindGrid();
 }

更新 注意:我看到您在过程中将 DB 和 Schema 作为参数传递,但在连接字符串中您将定义它,当您从 SQL 执行但进入应用程序时您不需要使用它时会很有用它们是因为您将说明 web-config which database 和 schema ,因此它将是多余的。

【讨论】:

  • 我已经检查过了,但现在它跳过了 if 部分。这个语句 [int i =cmd.ExecuteNonQuery();] 给 i 赋予 -1 值
  • @Iqraa 啊明白了
  • @Iqraa String value = TextBox1.Text.ToString(); 在此您不需要将其转换为字符串,而且,您在将值传递给存储过程时是否遵循相同的顺序,它应该是相同的顺序和相同的名称(我的意思是区分大小写)
  • 是的,我以正确的顺序将值传递给 SP
  • @Iqraa 我看到你正在传递数据库和模式作为过程中的参数,但在连接字符串中你将定义这个,这里说明它们的原因是什么?
猜你喜欢
  • 2014-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多