2017-02-16 51 views
0

我可以問爲什麼彈出消息在ID附近出現錯誤,我找不到解決方案。它在我點擊按鈕後彈出這條消息。消息:「ID」附近的語法不正確

消息:附近有語法錯誤 'ID'

public override bool fnSaveNewRecord() 
{ 
    DataSet _ds; 
    string _sql; 
    object _obj; 

    _sql = "INSERT INTO do_information(die_class_code,subinvetory_code,contact_code,company_code, " + 
      "corg_code,created_on,created_by) " + 
      "VALUES '" + txt_CodeID.Text.Trim() + "','" + cbx_SubInventoryCode.Text + "'," + 
      "'" + cbx_ContactCode.Text + "','" + cbx_CompanyCode.Text + "','" + cbx_CorgCode.Text + "','" + 
      "',GETDATE(),'" + App_Common._USER_CODE + "'"; 

    _ds = new DataSet(); 
    _obj = new SqlDatabase(App_Common._WSFCSConnStr) as SqlDatabase; 
    _ds = ((SqlDatabase)_obj).ExecuteDataSetQ(_sql); 

    return base.fnSaveNewRecord(); 
} 
+5

您需要使用'VALUES(v1,v2,...)' - 所以使用括號。 –

+7

您應該使用參數化查詢,而不是將值連接到查詢字符串中。您當前的解決方案容易受到SQL注入的影響,並且存在安全漏洞。 –

+0

OT的一些言論:a)你已經創建了一個不需要'作爲SqlDatabase'的東西; b)你不需要'_ds = new DataSet();'因爲你會*覆蓋你的ExecuteDataSetQ調用中的空數據集; c)你似乎沒有使用'_ds'(你不需要它插入),是否有一個簡單的Execute方法,你可以使用? –

回答

0

你的SQL查詢是錯誤的:

_sql = "INSERT INTO do_information(die_class_code,subinvetory_code,contact_code,company_code, " + 
       "corg_code,created_on,created_by) " + 
       "VALUES ('" + txt_CodeID.Text.Trim() + "','" + cbx_SubInventoryCode.Text + "'," + 
       "'" + cbx_ContactCode.Text + "','" + cbx_CompanyCode.Text + "','" + cbx_CorgCode.Text + "','" + 
       "',GETDATE(),'" + App_Common._USER_CODE + "')"; 

你的值必須在括號內。看看這個:

https://www.w3schools.com/sql/sql_insert.asp

3

嘗試使用此查詢:

_sql = "INSERT INTO do_information(die_class_code,subinvetory_code,contact_code,company_code, " + 
       "corg_code,created_on,created_by) " + 
       "VALUES('" + txt_CodeID.Text.Trim() + "','" + cbx_SubInventoryCode.Text + "'," + 
       "'" + cbx_ContactCode.Text + "','" + cbx_CompanyCode.Text + "','" + cbx_CorgCode.Text + "','" + 
       "',GETDATE(),'" + App_Common._USER_CODE + "'"+ "')'"; 

您已經使用括號內爲Values(v1,v2)作爲@Peter乙評論錯過。
看看this link作爲SQL插入語句的參考。

並且使用參數化查詢總比連接字符串總是更好,因爲它容易發生SQL注入攻擊。
Here是使用參數化查詢的參考。

希望這會有所幫助!

2

由於缺少括號,因此您的SQL語句錯誤。

代碼非常混亂,很難看到第一眼。所以你最好使用參數有一個更清潔的語句,你可以輕鬆地閱讀和檢查語法錯誤:

INSERT INTO do_information 
    (die_class_code, subinventory_code, contact_code, company_code, corg_code, created_on, created_by) 
VALUES 
    (@CodeId, @SubInventoryCode, @ContactCode, @CompanyCode, @CorgCode, GETDATE(), @UserCode) 

但是,你甚至可以做更多的得到這個代碼乾淨。包裝所有的查詢。這裏的發言爲例:

一些可重複使用的基礎聲明起

public interface IExecuteQuery 
{ 
    int Execute(); 
    Task<int> ExecuteAsync(CancellationToken cancellationToken); 
} 

public abstract class SqlExecuteQuery : IExecuteQuery 
{ 
    private readonly DbConnection _connection; 
    private readonly Lazy<DbCommand> _command; 

    protected SqlExecuteQuery(DbConnection connection) 
    { 
     if (connection == null) 
      throw new ArgumentNullException(nameof(connection)); 
     _connection = connection; 
     _command = new Lazy<DbCommand>(
      () => 
      { 
       var command = _connection.CreateCommand(); 
       PrepareCommand(command); 
       return command; 
      }); 
    } 

    protected abstract void PrepareCommand(DbCommand command); 

    protected DbCommand Command => _command.Value; 

    protected virtual string GetParameterNameFromPropertyName(string propertyName) 
    { 
     return "@" + propertyName; 
    } 

    protected T GetParameterValue<T>([CallerMemberName] string propertyName = null) 
    { 
     object value = Command.Parameters[ GetParameterNameFromPropertyName(propertyName) ].Value; 
     if (value == DBNull.Value) 
     { 
      value = null; 
     } 
     return (T) value; 
    } 

    protected void SetParamaterValue<T>(T newValue, [CallerMemberName] string propertyName = null) 
    { 
     object value = newValue; 
     if (value == null) 
     { 
      value = DBNull.Value; 
     } 
     Command.Parameters[ GetParameterNameFromPropertyName(propertyName) ].Value = value; 
    } 

    protected virtual void OnBeforeExecute() { } 

    public int Execute() 
    { 
     OnBeforeExecute(); 
     return Command.ExecuteNonQuery(); 
    } 

    public async Task<int> ExecuteAsync(CancellationToken cancellationToken) 
    { 
     OnBeforeExecute(); 
     return await Command.ExecuteNonQueryAsync(cancellationToken); 
    } 
} 

public static class DbCommandExtensions 
{ 
    public static DbParameter AddParameter(this DbCommand command, Action<DbParameter> configureAction) 
    { 
     var parameter = command.CreateParameter(); 
     configureAction(parameter); 
     command.Parameters.Add(parameter); 
     return parameter; 
    } 
} 

現在定義一個接口的發言

public interface IInsertInformationQuery : IExecuteQuery 
{ 
    string CodeId { get; set; } 
    string SubInventoryCode { get; set; } 
    string ContactCode { get; set; } 
    string CompanyCode { get; set; } 
    string CorgCode { get; set; } 
    string UserCode { get; } 
} 

實施

public class SqlInsertInformationQuery : SqlExecuteQuery, IInsertInformationQuery 
{ 
    public SqlInsertInformationQuery(DbConnection connection) : base(connection) 
    { 
    } 

    protected override void OnBeforeExecute() 
    { 
     UserCode = App_Common._USER_CODE; // this should be injected 
    } 

    protected override void PrepareCommand(DbCommand command) 
    { 
     command.CommandText = 
      @"INSERT INTO do_information (die_class_code, subinventory_code, contact_code, company_code, corg_code, created_on, created_by) " + 
      @"VALUES (@CodeId, @SubInventoryCode, @ContactCode, @CompanyCode, @CorgCode, GETDATE(), @UserCode)"; 

     command.AddParameter(p => 
     { 
      p.ParameterName = "@CodeId"; 
      p.DbType = System.Data.DbType.String; 
      p.Direction = System.Data.ParameterDirection.Input; 
     }); 
     command.AddParameter(p => 
     { 
      p.ParameterName = "@SubInventoryCode"; 
      p.DbType = System.Data.DbType.String; 
      p.Direction = System.Data.ParameterDirection.Input; 
     }); 
     command.AddParameter(p => 
     { 
      p.ParameterName = "@ContactCode"; 
      p.DbType = System.Data.DbType.String; 
      p.Direction = System.Data.ParameterDirection.Input; 
     }); 
     command.AddParameter(p => 
     { 
      p.ParameterName = "@CompanyCode"; 
      p.DbType = System.Data.DbType.String; 
      p.Direction = System.Data.ParameterDirection.Input; 
     }); 
     command.AddParameter(p => 
     { 
      p.ParameterName = "@CorgCode"; 
      p.DbType = System.Data.DbType.String; 
      p.Direction = System.Data.ParameterDirection.Input; 
     }); 
     command.AddParameter(p => 
     { 
      p.ParameterName = "@UserCode"; 
      p.DbType = System.Data.DbType.String; 
      p.Direction = System.Data.ParameterDirection.Input; 
     }); 
    } 

    public string CodeId 
    { 
     get => GetParameterValue<string>(); 
     set => SetParamaterValue(value); 
    } 
    public string SubInventoryCode 
    { 
     get => GetParameterValue<string>(); 
     set => SetParamaterValue(value); 
    } 
    public string ContactCode 
    { 
     get => GetParameterValue<string>(); 
     set => SetParamaterValue(value); 
    } 
    public string CompanyCode 
    { 
     get => GetParameterValue<string>(); 
     set => SetParamaterValue(value); 
    } 
    public string CorgCode 
    { 
     get => GetParameterValue<string>(); 
     set => SetParamaterValue(value); 
    } 

    public string UserCode 
    { 
     get => GetParameterValue<string>(); 
     private set => SetParamaterValue(value); 
    } 

} 

最後你的代碼看起來像

public override bool fnSaveNewRecord() 
{ 
    var database = new SqlDatabase(App_Common._WSFCSConnStr); 
    using (var connection = database.CreateConnection()) 
    { 
     connection.Open(); 
     IInsertInformationQuery query = new SqlInserInformationQuery(connection); 

     query.CodeId = txt_CodeID.Text.Trim(); 
     query.SubInventoryCode = cbx_SubInventoryCode.Text; 
     query.ContactCode = cbx_ContactCode.Text; 
     query.CompanyCode = cbx_CompanyCode.Text; 
     query.CorgCode = cbx_CorgCode.Text; 

     var recordsAffected = query.Execute(); 
    } 
    return base.fnSaveNewRecord(); 
}