【问题标题】:SQL Server Insert with variable column names, variable column values and an unknown number of columns具有可变列名、可变列值和未知列数的 SQL Server 插入
【发布时间】:2019-12-31 04:41:26
【问题描述】:

我正在创建一个项目,我需要在其中显示多个表,每个表都在一个 db 网格上,并且所有表都有 CRUD,问题是它有很多表,所以我正在动态生成不同的 UI对于所有表并编写一种大小适合它们的所有 CRUD 存储过程。

此时除了插入之外一切都在工作,因为它是不同的表,这意味着变量表名、列名、列值和列数,每个表还允许空值并且不允许在不同位置的列使用空值。

我所做的更新是使用动态 SQL 并使用变量表名、列名、列值、列 ID 名称和列 ID 值,然后循环给定表的列数,这种方法将但是不适用于插入,我尝试只为其余字段插入具有默认值的主键,然后我将在插入后立即更新默认值但它不起作用,因为列数也是可变的事实上,一列可以允许空值,而另一列在不同的表中,而位置则不允许。

我对 SQL 很陌生,我确信必须有办法做到这一点,但在网上搜索了几个小时后,我找不到任何东西,提前感谢您的帮助。

DECLARE @str AS VARCHAR(MAX) 

SET @str = N'UPDATE DBName..' + quotename(@tableName) + ' SET ' +quotename(@colName)+ ' = ''' +@colValue+ ''' WHERE ' +quotename(@colID)+ ' = ' +CAST(@colIDValue AS NVARCHAR(255))+ '';

EXEC (@str)

rgv = (Telerik.WinControls.UI.RadGridView)tConParamTables.SelectedTab.Controls[3];

currentTableName = tConParamTables.SelectedTab.Name;
string colName = "", colValue = "", colID = "";
int colIDValue = 0;

for (int i = 1; i < numberOfCols; i++)
{
    txtBoxUpdate = updateTxtBoxList[i];
    colName = commaSepCols[i];
    colValue = txtBoxUpdate.Text;
    colID = commaSepCols[0];
    colIDValue = Convert.ToInt16(rgv.SelectedRows[0].Cells[0].Value);
    SetParamTables(_DBCONN, colName, colValue, currentTableName, colID, colIDValue, ref paramsTableSet);
}

selectRow();
updateForm.Dispose();

编辑: 我已经搜索并尝试了许多不同的方法来解决这个问题,并找到了一种可行的解决方案。

首先: 我使用它来获取给定表的列和相应的数据类型,给定的表是传递给它的参数,但为简单起见,我在这里使用了 'TableName'。

SELECT COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName';

所以我现在有了列名,这意味着我也知道表中有多少列,但我不知道如何在插入语句中使用它。

我当前的插入看起来像这样:

SET @str = N'INSERT INTO DBName..' + quotename(@tableName) + 
            '(' + quotename(@colName) + ')' + 
            'VALUES' + '(' + CAST(@colValue AS NVARCHAR(255)) + ')'

如果不是因为如果我循环它以获取列的数量,这可能会起作用,它每次都会在新行上执行新的插入。

【问题讨论】:

  • “我正在创建一个项目,我需要在其中显示多个表,每个表都在一个 db 网格上,并且对所有表都有 CRUD”——这本身就会引发危险信号.....
  • 你的意思是同时处理多个表是个坏主意吗?
  • 我的意思是这通常是个坏主意。出于多种原因,让最终用户编辑“原始”数据是一个糟糕的设计选择。
  • 你看过“Django”吗?
  • 本地托管的网络应用程序。和桌面应用程序。与 sql server 对话并没有什么不同。

标签: c# sql-server winforms


【解决方案1】:

我得到了它的工作,有点混乱,所以在此期间将寻找更好的方法,例如代替在 c# 中生成字符串以在存储过程中使用 while 循环生成它们,我当前的解决方案是构建一个字符串列名和值,并将它们作为参数传递给我的存储过程。

C#:

        currentTableName = tConParamTables.SelectedTab.Name;
        string colName = "", colValue = "", colValueList = "", colNameList = "";

        txtBoxCreate = insertTxtBoxList[0];
        colNameList = commaSepCols[0];
        colValueList = txtBoxCreate.Text;

        for (int i = 1; i < numberOfCols; i++)
        {
            txtBoxCreate = insertTxtBoxList[i];
            colName = commaSepCols[i];
            colValue = txtBoxCreate.Text;
            colNameList = colNameList + "," + colName;
            colValueList = colValueList + "'" + "," + "'" + colValue;
        }

        InsertParamTables(_DBCONN, currentTableName, colNameList, colValueList);
        selectLastRow();
        createForm.Dispose();

SQL:

DECLARE @str AS VARCHAR(MAX) 

SET @str = N'INSERT INTO DBName..' + quotename(@tableName) + '(' + @colNameList + ')' + 'VALUES' + '(''' + @colValueList + ''')';

EXEC (@str)

【讨论】:

    猜你喜欢
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多