2012-04-21 8 views
0

私はテーブルにいくつかの値を挿入するだけの機能を持っています。npgsqlを使用したinsert-functionでの奇妙な構文エラー

CREATE OR REPLACE FUNCTION register_new_user(
    pnick character varying 
, ppasshash character varying 
, pmail character varying 
) 
RETURNS void AS 
$BODY$ 
Declare 
Begin 
Insert into registration 
values(pNick, pPasshash, pMail); 
End; 
$BODY$ LANGUAGE plpgsql; 

今、私は

Select register_new_user('a','b','c') as Answer; 

ようpgAdminでは、この機能を使用するときにはうまく動作しますが、私は私の.NET-Databasemanagementを経由してそれを実行しようとしたとき、私は$ 2のNpgsqlのから構文エラーが出ます(それは例外が言うものです)。

Using func As DatabaseFunction = DatabaseFunction.CreateNewFunctionInstance("register_new_user") 
    func.AddParameter("pnick", txt_Nick.Text, Data.ParameterDirection.Input) 
    func.AddParameter("ppasshash", passhash, Data.ParameterDirection.Input) 
    func.AddParameter("pmail", txt_Mail.Text, Data.ParameterDirection.Input) 
    func.ExecuteNonQuery() 
End Using 

passhashの場合、それは「こんにちは」は動作しません。でも、私はそこに書かれたものは気にしません:

これは、私はVB.NETを経由して関数を呼び出す方法です。私はパスハッシュのためにUTF8-Encodingを使用し、接続文字列でもそう言います。私の.NET-とプログラムのための私のdatabasemanagementは、次のようになります。

Public Class DatabaseFunction 
      Implements IDisposable 
      Public dbcon As IDbConnection 
      Private comm As NpgsqlCommand 
      Public trans As IDbTransaction 
      Private funcname As String = String.Empty 
      Private dr As IDataReader = Nothing 
      Public Sub New(ByVal functionname As String, ByVal Connection As IDbConnection, ByVal Transaction As IDbTransaction) 
       Try 
        dbcon = Connection 
        trans = Transaction 
        funcname = functionname 
        comm = New NpgsqlCommand(functionname, dbcon, trans) 
        comm.CommandType = CommandType.StoredProcedure 
       Catch ex As Exception 
        Throw New Exception("Fehler bei der Initierung einer Datenbankfunktion: " & ex.Message) 
       End Try 
      End Sub 

      Public Shared Function CreateNewFunctionInstance(ByVal FunctionName As String) As DatabaseFunction 
       Try 
        Dim dbcon As IDbConnection = DatabaseConnection.CreateNewOpenConnection() 
        Return New DatabaseFunction(FunctionName, dbcon, dbcon.BeginTransaction) 
       Catch ex As Exception 
        Throw ex 
       End Try 
      End Function 

      Public Sub AddParameter(ByVal Name As String, ByVal parameter As Object, ByVal Direction As ParameterDirection) 
       Try 
        Dim newparam As NpgsqlParameter = comm.CreateParameter() 
        newparam.ParameterName = Name 
        newparam.Value = parameter 
        newparam.Direction = Direction 
        comm.Parameters.Add(newparam) 
       Catch ex As Exception 
        Throw ex 
       End Try 
      End Sub 

      Public Function ExecuteReader() As IDataReader 
       Try 
        comm.Connection = dbcon 
        comm.Transaction = trans 
        comm.Prepare() 
        dr = DirectCast(comm.ExecuteReader(), IDataReader) 
        Return dr 
       Catch ex As Exception 
        Throw ex 
       End Try 
      End Function 

      Public Sub ExecuteNonQuery() 
       Try 
        comm.Connection = dbcon 
        comm.Transaction = trans 
        comm.Prepare() 
        comm.ExecuteNonQuery() 
       Catch ex As Exception 
        Throw ex 
       End Try 
      End Sub 

      Public Shared Function CreateNewDatabaseConnection() As IDbConnection 
       Try 
        Return DatabaseConnection.CreateNewOpenConnection() 
       Catch ex As Exception 
        Throw ex 
       End Try 
      End Function 

      Public Sub Dispose() Implements IDisposable.Dispose 
       Try 
        If Not dr Is Nothing Then 
         If Not dr.IsClosed Then 
          dr.Close() 
          dr.Dispose() 
         End If 
        End If 
        trans.Commit() 
        comm.Dispose() 
        dbcon.Close() 
        dbcon.Dispose() 
       Catch ex As Exception 
        Throw ex 
       End Try 
      End Sub 
     End Class 

誰かが私はそれがここにナット私を運転している原因この問題を修正するために喜ば助けることができます。


最近、Syntaxerrorがcommand.prepare() - Subによって引き起こされていることがわかりました。私が自分のものを直接実行すると、うまく動作します。

答えて

1

それはあなたがここに代わりに(単一引用符で)テキスト'1234'の数1234を渡すこともできます:

... 
func.AddParameter("ppasshash", passhash, Data.ParameterDirection.Input) 
... 

それはないもあなたの問題、データベースログの意志を見て解決した場合。標準構成では、実際にデータベースに送信されたステートメントを含む、より冗長なエラーメッセージが表示されます。あなたのpostgresql.confファイルでlog_destinationため

syntax error at $2 

ルック:
PostgreSQLはちょうどより、このような場合には言うことはもっとたくさんあります。ロギングが定義されています。

CREATE OR REPLACE FUNCTION register_new_user(
    _pnick text 
,_ppasshash text 
,_pmail text 
) 
    RETURNS void AS 
$BODY$ 
INSERT INTO registration (pnick, ppasshash, pmail) -- assuming these col names 
VALUES($1, $2, $3); 
$BODY$ LANGUAGE sql; 
  • ここにPL/pgSQLの(それは確かに可能であるが)、無地の必要はありません。
    More about where to log in the manual here.


    あなたは/簡素化し、あなたのPostgreSQLの機能を改善することができますSQL関数はトリックを行います。

  • を(あなたはしかし、SQL関数の関数本体に番号パラメータ($ 1、$ 2、..)を使用する必要があります)常に機能でINSERTのターゲットリストを使用します。 それ以外のテーブルが変更された場合、予期しない方法で破損します。

  • パラメータ名を一意にすることで名前の競合を回避します。私は_プレフィックスを使用するのが好きですが、それは私の任意の選択です。

+0

あなたの数字推測はこのパズルの解決ではありませんでした。あなたはそれらのログをどこに見つけるか教えていただけますか?私はpostgreにかなり新しいです... – Husky110

+0

@ Husky110:私は私の答えに少しを追加しました。 –

+0

あなたの時間に感謝しますが、問題は、機能自体が完璧に動作するということです。問題はプログラムコードのどこかにあると思う。エディタから実行すると完璧に機能するからだ。私はinsert-targetlistの問題を認識しており、変数とcollumnの衝突を避けるためにpをプレフィックスとして使用しています。 – Husky110