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 执行此操作时,我在 2 美元处收到来自 npgsql 的语法错误(这就是异常所说的)。

这就是我通过 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 的情况下,它并不关心我在那里写的内容,即使“你好”也不起作用。我对密码使用 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、..))

  • 始终INSERT为in 函数使用目标列表。否则,如果基础表发生更改,它将以意想不到的方式中断。

  • 通过使参数名称唯一来避免命名冲突。我喜欢为此使用_前缀,但这是我的任意选择。

于 2012-04-21T19:13:55.737 回答