【问题标题】:C#, sqlcommand stringC#,sql命令字符串
【发布时间】:2016-08-05 18:08:47
【问题描述】:

我有一个 SqlCommand 字符串来创建一个 SqlServer 数据表,如下所示:

`string EFTGeneral = @`"CREATE TABLE [EFT.GER2] (
                                [TestOrderName]   VARCHAR(20)  NOT NULL,    
                                [Template]        VARCHAR(50)  NULL,
                                [Purpose]         VARCHAR(100) NULL,
                                [Category]        VARCHAR(50)  NULL,
                                [DateCreated]         DATETIME NULL,
                                [CreatedBy]       VARCHAR(30)  NULL,
                                [TestObjectBatch] VARCHAR(20)  NULL,
                                [LoadDirection]   VARCHAR(2)   NULL,
                                [ElementType]     VARCHAR(10)  NULL,
                                [FatigueTestType] VARCHAR(50)  NULL,
                                [LoadAmplitude]            INT NULL,
                                [LoadStatic]      INT NULL,
                                [UntilBreakage]   VARCHAR(5)   NULL,
                                [NumberOfObject]           INT NULL,
                                [Remarks]         VARCHAR(200) NULL,
                                PRIMARY KEY CLUSTERED([TestOrderName] ASC));";

但我想通过将上面字符串中的表名替换为 textbox.Text 来动态创建表名,我该怎么做?非常感谢

【问题讨论】:

    标签: c# sqlcommand


    【解决方案1】:

    通常我会说“不要这样做”,因为在查询中插入用户输入会打开SQL injection 漏洞。正确的方法是使用参数化查询。

    不幸的是,参数只能用于值,而不能用于表或列名。因此,要轻松替换查询中的表名,您可以像这样简单地执行Replace()

    EFTGeneral = EFTGeneral.Replace("[EFT.GER2]", "[" + textBox.Text + "]");
    

    但是您应该确保textBox.Text 是一个有效的表名,而不是像"; DROP TABLE Users --" 这样的名称。 This answer 展示了如何验证表名。

    【讨论】:

    • 亲爱的大家,非常感谢您的快速回答。我解决了这个问题:
    【解决方案2】:

    这是我的代码,现在我可以根据需要创建 SQL 表名称:

    try
                {
                   string EFTGeneral = @"CREATE TABLE [EFTGNR] (
                                    [TestOrderName]   VARCHAR(20)  NOT NULL,    
                                    [Template]        VARCHAR(50)  NULL,
                                    [Purpose]         VARCHAR(100) NULL,
                                    [Category]        VARCHAR(50)  NULL,
                                    [DateCreated]         DATETIME NULL,
                                    [CreatedBy]       VARCHAR(30)  NULL,
                                    [TestObjectBatch] VARCHAR(20)  NULL,
                                    [LoadDirection]   VARCHAR(2)   NULL,
                                    [ElementType]     VARCHAR(10)  NULL,
                                    [FatigueTestType] VARCHAR(50)  NULL,
                                    [LoadAmplitude]            INT NULL,
                                    [LoadStatic]      INT NULL,
                                    [UntilBreakage]   VARCHAR(5)   NULL,
                                    [NumberOfObject]           INT NULL,
                                    [Remarks]         VARCHAR(200) NULL,
                                    PRIMARY KEY CLUSTERED([TestOrderName] ASC));";
                    ////
    
                    SqlConnection conn = new SqlConnection(ConnString);
                    conn.Open();
                    EFTGeneral = EFTGeneral.Replace("[EFTGNR]", "[" + txtbox_testorder.Text + ".GERNERAL]");
                    SqlCommand cmd = new SqlCommand(EFTGeneral, conn);
                    cmd.ExecuteNonQuery();
                    conn.Close();
                }catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
    

    【讨论】:

      【解决方案3】:

      使用SqlCommand 动态构建查询以避免注入风险:

      string EFTGeneral = @"CREATE TABLE [EFT.@tableName] (
                                      [TestOrderName]   VARCHAR(20)  NOT NULL,    
                                      [Template]        VARCHAR(50)  NULL,
                                      [Purpose]         VARCHAR(100) NULL,
                                      [Category]        VARCHAR(50)  NULL,
                                      [DateCreated]         DATETIME NULL,
                                      [CreatedBy]       VARCHAR(30)  NULL,
                                      [TestObjectBatch] VARCHAR(20)  NULL,
                                      [LoadDirection]   VARCHAR(2)   NULL,
                                      [ElementType]     VARCHAR(10)  NULL,
                                      [FatigueTestType] VARCHAR(50)  NULL,
                                      [LoadAmplitude]            INT NULL,
                                      [LoadStatic]      INT NULL,
                                      [UntilBreakage]   VARCHAR(5)   NULL,
                                      [NumberOfObject]           INT NULL,
                                      [Remarks]         VARCHAR(200) NULL,
                                      PRIMARY KEY CLUSTERED([TestOrderName] ASC));";
      
      using (SqlConnection connection = new SqlConnection(yourConnectionString))
      {
          using (SqlCommand command = new SqlCommand(EFTGeneral, connection))
          {
              SqlParameter tableNameParam = new SqlParameter("tableName", SqlDbType.Varchar);
              tableNameParam.Value = textBox.Text;
              command.Parameters.Add(tableNameParam);
              command.ExecuteNonQuery();
          }
      }
      

      【讨论】:

      • 谢谢。我也会尝试你的帮助。
      • 请注意我在代码中修复了CREATE TABLE [EFT.@tableName] (
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      • 1970-01-01
      • 2017-11-11
      • 2020-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多