我目前正在使用c#和sql服务器管理工作室:
我有一个像这样的表
+--------+-------------+-------------+------+
| TaskId | Item2(bool) | Item3(bool) | etc… |
+--------+-------------+-------------+------+
我不知道bool列名,因为它们是通过代码(用户创建它们)创建的。
好吧,我在窗体打开时插入数据,使用TaskId和所有bools
和DEFAULT(0)
,因为我有类似的东西:
+--------------------------------------+-------------+-------------+------+
| TaskId | Item2(bool) | Item3(bool) | etc… |
+--------------------------------------+-------------+-------------+------+
| 9B093907-2072-4F59-A55C-0003CE89EF9E | 0 | 0 | 0 |
+--------------------------------------+-------------+-------------+------+
我想更新布尔值,因此在C#中我创建了数据表以使用User-defined tables
:
DataTable checkboxList = new DataTable();
var checkboxNameColumn = checkboxList.Columns.Add("CheckBoxName", typeof(string));
var checkBoxValueColumns = checkboxList.Columns.Add("CheckBoxValue", typeof(bool));
foreach (var c in checkBoxes)
{
var row = checkboxList.NewRow();
row[checkboxNameColumn] = c.Name;
row[checkBoxValueColumns] = c.Checked;
checkboxList.Rows.Add(row);
}
Guid currentUser = new Guid(EBResources.EmpGuid);
Guid currentTaskId = new Guid(TaskId);
db.ExeSQLRedMarkItems($"usp_RedMarkItem_Insert", checkboxList, "@CheckBoxList", currentTaskId, currentUser);
CheckBoxName等于我的列名,CheckBoxValue
是该列的值。所以我的Datatable
是正确的,现在我将其发送给sql:
用户定义表
CREATE TYPE [HELPER].CheckBoxValues AS TABLE(
CheckBoxName VARCHAR(255) NOT NULL,
CheckBoxValue BIT NOT NULL )
存储过程:
CREATE OR ALTER PROCEDURE [dbo].[usp_RedMarkItem_Insert]
-- Add the parameters for the stored procedure here
@TaskId UNIQUEIDENTIFIER
, @CheckBoxList [Helper].[CheckBoxValues] READONLY
, @CurrentUser UNIQUEIDENTIFIER
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @CurrentCheckboxName VARCHAR(255) = (SELECT
[CheckBoxName]
FROM @CheckBoxList)
UPDATE [m]
SET
@CurrentCheckboxName = [c].[CheckBoxValue]
FROM [RedMarkItems] [m]
JOIN @CheckBoxList [c] ON [c].[CheckBoxName] = @CurrentCheckboxName
WHERE m.TaskId = @TaskId
END
如您所见,我声明了@CurrentCheckboxName
,但由于选择返回多个值,因此抛出了错误:
子查询返回了多个值。当 子查询遵循=,!=,<,<=,>,> =,或当子查询用作 表达式。
我需要做些什么来在列名之间进行迭代?问候
答案 0 :(得分:0)
您不需要下面的行
DECLARE @CurrentCheckboxName VARCHAR(255) = (SELECT
[CheckBoxName]
FROM @CheckBoxList)
您已经在@CheckBoxList中拥有了它。您需要以下类似的内容
UPDATE [m]
SET m.val = [c].Val
JOIN @CheckBoxList [c]
ON [c].[CheckBoxName] = m.CheckBoxName
WHERE m.TaskId = @TaskId
您可以从Information_schema获取列名
SELECT
TABLE_NAME,
COLUMN_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
答案 1 :(得分:0)
您的数据库设计将给您带来很多问题。 SQL Server最适合使用具有指定数量的命名列的预定义表:虽然可以将系统设置为具有用户定义的字段标签,但是从某种意义上说,具有实际的用户定义的 fields 创建在数据库之上运行的数据库。要使用和管理这些基础结构,您将需要大量尚未创建的基础结构。
我的建议:如果您需要一行包含用户定义的布尔值的集合,请将布尔值存储为XML。
CREATE TABLE dbo.Task
(
TaskId int,
Checkboxes xml
)
您的XML将被定义为这样(尽管您可以通过多种方法来定义它!)
<Checkboxes>
<Checkbox name="User-defined name" value="True" />
<Checkbox name="Some other name" value="False" />
</Checkboxes>
您仍然会遇到一些挑战-例如,如果要提取所有具有复选框“ Apple”且值为true
的行-但您的行数会少于您将使用实际的用户定义表。
实际上,以一种有用的方式查询XML是可能的。