0

テーブルにいくつかの値を単純に挿入する関数があります。

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;

今、pgAdminでこの機能を使用すると

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

それは問題なく動作しますが、.NET-Databasemanagement を介して実行しようとすると、npgsql から $2 で構文エラーが発生します (これが例外の意味です)。

これは、VB.NET 経由で関数を呼び出す方法です。

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 の場合、そこに何を書いてもかまいません。"hello" でさえ機能しません。私はパスハッシュにUTF8エンコーディングを使用し、接続文字列でもそれを言います。私の .NET プログラムのデータベース管理は次のようになります。

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 によって引き起こされていることがわかりました。自分のものを直接実行すると、正常に動作します。

4

1 に答える 1

1

1234ここでテキスト(一重引用符付き)の代わりに数値を渡すことはできますか'1234'

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

それでも問題が解決しない場合は、データベース ログを確認してください。標準構成では、実際にデータベースに送信されたステートメントを含む、より詳細なエラー メッセージが表示されます。
このような場合、PostgreSQL には次のこと以外にも多くのことが言えます。

syntax error at $2

ファイルで を探しlog_destinationますpostgresql.conf。ロギングはそこで定義されています。
マニュアルのログイン場所の詳細については、こちらをご覧ください。


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 は必要ありません (確かに可能ですが)、単純な SQL 関数でうまくいきます。(ただし、SQL 関数の関数本体では、番号付きパラメーター ($1、$2、..) を使用する必要があります)

  • in 関数には常にターゲット リストを使用INSERTします。それ以外の場合、基になるテーブルが変更されると、予期しない方法で破損します。

  • パラメータ名を一意にすることで、名前の競合を回避します。そのために接頭辞を使用したいの_ですが、それは私の恣意的な選択です。

于 2012-04-21T19:13:55.737 に答える