【问题标题】:How to declare sql variable in C#如何在 C# 中声明 sql 变量
【发布时间】:2015-03-20 20:10:41
【问题描述】:

我的要求是从表中删除除一个之外的所有记录。为此,我正在执行一系列两个不同的sql 命令。好像在ssms 上工作正常,但使用 C# 就不行了

--This is what I run on ssms without any issue
DECLARE @int INT;
SELECT @int  =  COUNT(*) 
FROM [Table] 
WHERE STATE = 'CO';

--Delete statement
DELETE TOP (@int - 1 ) 
FROM [Table] ;

public static void ClearData(string state)
{
    const string queryToExec = @"DECLARE @int INT;" +
                               "SELECT @int  =  COUNT(*) " +
                               "FROM [Table] " +
                               "WHERE STATE = @State;" +
                               "DELETE TOP (@int - 1 ) " + //NOTICE THIS LINE
                               "FROM [Table] ";

    List<SqlParameter> param = new List<SqlParameter>()
    {
        new SqlParameter {ParameterName = "@State", SqlDbType = SqlDbType.VarChar, Value = state},
    };

    ExecQuery(queryToExec, param);
}

public static void ExecQuery(string query, List<SqlParameter> paramCollection = null)
{
    using (SqlConnection conn = new SqlConnection(ConnString))
    {
        using (SqlCommand mySqlCom = new SqlCommand())
        {
            mySqlCom.CommandText = query;
            if (paramCollection != null) mySqlCom.Parameters.AddRange(paramCollection.ToArray());
            mySqlCom.Connection = conn;
            conn.Open();
            mySqlCom.ExecuteNonQuery();
        }
    }
}

我的qsns

  1. 如何在 C# 中正确声明 sql 变量(参见 ClearData 方法)
  2. 以及,如何在单个查询字符串中执行多个查询?(如果我这样做是正确的)

编辑

我想出了这个来完成这个。但现在还是运气。请告诉我该怎么做:

IF OBJECT_ID ( 'uspWageDataByState', 'P' ) IS NOT NULL 
    DROP PROCEDURE uspWageDataByState;
GO

CREATE PROCEDURE uspWageDataByState
    @State NVARCHAR(2)  
AS

    DECLARE @int INT
    SET @int  =  (SELECT COUNT(*) 
    FROM [Test] 
    WHERE [STATE] = @State)

    DELETE TOP (@int - 1 ) 
    FROM [Test]
    WHERE [STATE] = @State;

GO

exec uspWageDataByState 'CO'

【问题讨论】:

  • 最好创建一个Stored Proc 并调用它。
  • @RahulSingh 感谢您的建议。我不能在数据库中存储任何东西,而且说实话我确信这不是最好的方法。您能否为这两个语句写一个存储过程。我不是 sql 专家,我需要在我的 C# 代码中做所有事情
  • 我不能重复这个 - 它对我有用。您在批处理中声明多个语句很好 - ORM 和数据访问层一直这样做,例如在准备sp_executesql时。好的做法是建议转义列[State],并明确设置cmd.CommandType = Text,但无论如何这是默认设置。根据 Rahul 的说法,proc 也是一个好主意。出于兴趣,您是否也想删除WHERE [State] = 'co',否则您将修剪所有记录?
  • @RahulSingh 我创建了您建议的存储专业版,但无法正常工作,请告诉我出了什么问题
  • @StuartLC 查看存储过程。谢谢

标签: c# sql sql-server sql-server-2008 database-connection


【解决方案1】:

我已经在我的环境中准确地运行了这段代码,它按预期工作。

我的框架版本是 4.5.51641,我的 SQL 版本是 SQL Server 11.0.2100

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Data;

namespace PruebasSQL
{
    class Program
    {
        const string ConnString = @"";

        static void Main(string[] args)
        {
            ClearData("A");
        }

        public static void ClearData(string state)
        {
            const string queryToExec = @"DECLARE @int INT;" +
                                       "SELECT @int  =  COUNT(*) " +
                                       "FROM [Table] " +
                                       "WHERE STATE = @State;" +
                                       "DELETE TOP (@int - 1 ) " + //NOTICE THIS LINE
                                       "FROM [Table] ";

            List<SqlParameter> param = new List<SqlParameter>()
            {
                new SqlParameter {ParameterName = "@State", SqlDbType = SqlDbType.VarChar, Value = state},
            };

            ExecQuery(queryToExec, param);
        }

        public static void ExecQuery(string query, List<SqlParameter> paramCollection = null)
        {
            using (SqlConnection conn = new SqlConnection(ConnString))
            {
                using (SqlCommand mySqlCom = new SqlCommand())
                {
                    mySqlCom.CommandText = query;
                    if (paramCollection != null) mySqlCom.Parameters.AddRange(paramCollection.ToArray());
                    mySqlCom.Connection = conn;
                    conn.Open();
                    mySqlCom.ExecuteNonQuery();
                }
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    也许这可以帮助你,改变你的查询(queryToExec):

    ALTER PROCEDURE uspWageDataByState
    @State NVARCHAR(2)  
    AS
    
    DELETE TOP 
    (CASE 
        (SELECT COUNT(*) FROM [Test] WHERE [STATE] = @State) 
        WHEN 0 THEN 1 
        ELSE (SELECT COUNT(*) FROM [Test] WHERE [STATE] = @State) END -1) 
    FROM [Test]
    WHERE [STATE] = @State;
    

    如果声明的变量是您可以解决的问题,则不是最佳查询,但无论您使用什么都不是最佳形式:P。

    我正在添加一个 0 行验证,否则 sp 在找不到数据时崩溃。

    【讨论】:

      【解决方案3】:

      在单个字符串语句中执行多个查询:

      string querystring = "select [yourcolumns] from [yourtable];select [yourvalues] from [yourtables]";
      sqlcommand cmd  = new sqlcommand(querystring,yourconnection);
      sqlDataReader reader = cmd.executeReader();
      do
      {
       while(reader.Read())
      {
       //get your values here
      }
      }while(reader.NextResult());
      

      【讨论】:

        【解决方案4】:
        DECLARE @PageSize INT = 5, @PageNum   INT = 1
        SELECT tickets.ID, tickets.userID FROM tickets WHERE tickets.isActive = 1
        OFFSET (@PageNum-1)*@PageSize ROWS FETCH NEXT @PageSize ROWS ONLY
        

        这样在 aspnet sqlcommanddatareader 中工作

        【讨论】:

        • 5 = 在一页中的行数,顺便你可以将参数添加到 Page num 和 1 = pagenumber
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-13
        • 2015-05-04
        • 2022-06-17
        相关资源
        最近更新 更多