使用ADO.NET进行PostgreSQL参数化插入

时间:2015-08-22 15:54:45

标签: postgresql npgsql

我正在使用NpgSQL和PostgreSQL以及ADO.NET。原谅这个问题的简单性,因为我本周刚开始使用PostgreSQL和NpgSQL。

这样的事情很好:

[Test]
public void InsertNoParameters()
{
    NpgsqlConnection conn = new NpgsqlConnection("Host=localhost; Database=postgres; User ID=postgres; Password=password");
    conn.Open();

    IDbCommand command = conn.CreateCommand();
    string sql = "INSERT INTO Customers (FirstName,LastName) VALUES ('Test','Tube')";
    command.CommandText = sql;
    command.ExecuteNonQuery();
    conn.Close();
}

当我输入参数时,我收到错误消息: Npgsql.NpgsqlException:错误:42703:列“_firstname”不存在

[Test]
public void InsertWithParameters()
{
NpgsqlConnection conn = new NpgsqlConnection("Host=localhost; Database=postgres; User ID=postgres; Password=password");
conn.Open();

IDbCommand command = conn.CreateCommand();
string sql = "INSERT INTO Customers (FirstName,LastName) VALUES (_FirstName,_LastName)";
command.CommandText = sql;

var parameter = command.CreateParameter();
parameter.ParameterName = "_FirstName";
parameter.Value = "Test";
command.Parameters.Add(parameter);

parameter = command.CreateParameter();
parameter.ParameterName = "_LastName";
parameter.Value = "Tube";
command.Parameters.Add(parameter);

command.ExecuteNonQuery();
conn.Close();
}

1 个答案:

答案 0 :(得分:6)

评论中的回答是正确的:

  1. Npgsql不支持_作为参数占位符表示法。您应该使用@或:(所以@FirstName或:FirstName,而不是_FirstName)。
  2. PostgreSQL会自动小写你的表名和列名,除非它们是双引号。在SQL查询中使用小写名称(更简单)或引用标识符。
  3. 所以你的代码应该或多或少看起来像这样:

    namespace SomethingLikeStrategy
    {
      public interface Behaviour {
        void doThis();
        void changeM(ref int m);
        void doThat();
      }
    
      public class BehaviourOriginal : Behaviour {
        public void doThis() {
          Console.WriteLine("foo");
        }
        public void changeM(ref int m) {
          m = 20;
        }
        public void doThat() {
          throw new Exception("not implemented");
        }
      }
    
      public class BehaviourSpecial : Behaviour {
        public void doThis() {
          Console.WriteLine("bar");
        }
        public void changeM(ref int m) {
          m = 10;
        }
        public void doThat() {
          throw new Exception("not implemented");
        }
      }
    
      public class MyClass {
    
        Behaviour mBehaviour;
        int mM = 0;
    
        public MyClass() {
          mBehaviour = new BehaviourOriginal();
        }
    
        public void setSpecialBehaviour(bool special) {
          if (special) {
            mBehaviour = new BehaviourSpecial();
          } else {
            mBehaviour = new BehaviourOriginal();
          }
        }
    
        public void doThis() {
          mBehaviour.doThis();
        }
    
        public void doThat() {
          mBehaviour.doThat();
        }
    
        public void changeM() {
          mBehaviour.changeM(ref mM);
        }
    
        public void printM() {
          Console.WriteLine(mM);
        }
    
      }
    
      class Program
      {
        public static void Main(string[] args)
        {
          MyClass myClass = new MyClass();
          myClass.doThis();
          myClass.setSpecialBehaviour(true);
          myClass.doThis();
    
          myClass.setSpecialBehaviour(false);
          myClass.printM();
          myClass.changeM();
          myClass.printM();
          myClass.setSpecialBehaviour(true);
          myClass.changeM();
          myClass.printM();
    
          Console.Write("Press any key to continue . . . ");
          Console.ReadKey(true);
        }
      }
    }