【问题标题】:Use only one petition to server instead multiple只使用一份请愿书而不是多份
【发布时间】:2019-01-03 21:44:34
【问题描述】:

我有一个CheckBoxes 的列表:

List<CheckBox> checkBoxes = new List<CheckBox>();

我想通过存储过程更新它,所以我有:

private void btnSave_Click(object sender, EventArgs e)
{
    SQLConnMgr db = new SQLConnMgr();

    foreach (var c in checkBoxes)
    {
        db.ExeSQL($"exec test @CheckBoxName = {c.Name}, @CheckBoxValue = {c.Checked} ");
    }
}

存储过程:

CREATE OR ALTER PROCEDURE test 
    -- Add the parameters for the stored procedure here
    @CheckBoxName VARCHAR(255), 
    @CheckBoxValue BIT
AS
BEGIN
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    UPDATE MyTable SET @CheckBoxName = @CheckBoxValue
END

我的问题是:还有其他方法可以做到这一点吗?喜欢在 foreach 声明中发送多个请愿书,而不是一次只发送一个?

更新

所以为了更清楚,每个 bool 都是一列,所以我需要类似:

 DECLARE @CurrentCheckboxName VARCHAR(255) = (SELECT
                                                        [CheckBoxName]
                                                        FROM @CheckBoxList)

               UPDATE [m]
                SET
                    @CurrentCheckboxName = [c].[CheckBoxValue]
                    FROM [RedMarkItems] [m]
                        JOIN @CheckBoxList [c] ON [c].[CheckBoxName] = @CurrentCheckboxName

但是如何迭代我的 DECLARE 中的每个 checkboxName?

【问题讨论】:

  • 也许您可以尝试连接 SQL 语句?顺便说一句,您的 SQL 语言是什么? MySQL?甲骨文?还是什么?
  • 对不起,我正在使用 Sql 服务器管理 TSQL @Smankusors
  • 您可以在存储过程中使用 UDT 作为参数,并发送关于 UDT 的数据
  • 从技术上讲它可以工作,但从架构的角度来看,这不是一个好的解决方案,因为您将 GUI 前端粘合到数据库中!您的数据库不应依赖于任何前端 gui 元素名称。我会为复选框的含义使用逻辑唯一 ID,并在数据库中使用该 ID,这样数据库就不会依赖于任何 GUI 元素。
  • 你的意思是把exec test 放在你有exec MyTable 的地方吗?除非您还有一个未在此处显示的 MyTable 存储过程,否则当前形式的示例代码将无法工作...

标签: c# tsql


【解决方案1】:

根据您使用的 SQL Server 版本,您可以为存储过程使用 TABLE 参数类型并且只调用一次。

CREATE TYPE dbo.MyCheckBoxValues AS TABLE(
CheckBoxName VARCHAR(255) NOT NULL,
CheckBoxValue BIT NOT NULL )

然后你修改你的存储过程以使用该类型。

CREATE OR ALTER PROCEDURE test 
-- Add the parameters for the stored procedure here
@CheckBoxList MyCheckBoxValues READONLY
AS
BEGIN
SET NOCOUNT ON;

    -- Insert statements for procedure here
    UPDATE m SET CheckBoxValue=c.CheckBoxValue
    FROM MyTable m
    JOIN @CheckBoxList c ON c.CheckBoxName=m.CheckBoxName
END

您还可以在存储过程中使用动态 SQL。对于每个复选框值:

DECLARE @Query nvarchar(max); 
SET @Query = 'UPDATE Table SET ' + @CheckboxName + '='+ @CheckBoxValue; 
exec sp_executeSql @Query

那么您只需获取代码中的值。 应该这样做。

StringBuilder builder = new StringBuilder();

builder.Append("DECLARE @MyCheckboxes MyCheckBoxValues; ");

foreach (Guid id in _equipmentToMerge)
      {
        builder.Append(String.Format("INSERT INTO @MyCheckboxes (CheckBoxName, CheckBoxValue) VALUES ('{0}',{1}); ", name, ischecked));
      }

builder.Append("exec dbo.test @MyCheckboxes ");

【讨论】:

  • 你也可以挤一个DataTable:docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/…~防止SQL注入
  • Datatable怎么办,我首先需要创建tableas:DataTable MyTable = new DataTable();,那么他们的列或者行应该是什么? @Caramiriel
  • 是的,像这样,使用 Danielle 的 UDT 和存储过程:dotnetfiddle.net/APe7n5 - 手写输入,所以可能还有一些错误
  • 好吧,但是现在,在存储过程中,我不知道JOIN 中的m.CheckboxName,因为它是一个列名,对于SET [CheckBoxValue] @Caramiriel 可以是一样的和相同的跨度>
  • @Jonathan m.CheckboxName 应该是您的表“MyTable”中复选框的名称。由于您没有提供表的实际结构,我猜您可能有一个包含复选框名称的列。 (基于您提供的示例)或者我不确定我是否理解正确。每个复选框都有一个列名?
【解决方案2】:

我认为您的存储过程中的 Update 语句有问题。可以这样改吗?

    Update MyCheckBoxValues SET CheckBoxValue = @CheckBoxValue Where CheckBoxName = @CheckBoxName

我不知道你为什么要把事情复杂化。为循环使用单个连接,我无法想象您的表单上的复选框数量会令人望而却步。如果仍然太慢,请摆脱实体框架或您正在使用的任何形式,并尝试直接与服务器打交道。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 2015-01-06
    • 1970-01-01
    相关资源
    最近更新 更多