2012-04-21 71 views
0

我有一个函数,它只是将一些值插入到表中。插入函数使用npgsql时奇怪的语法错误

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的情况下,它并不关心什么,我在那里写的,甚至是“你好”是行不通的。我使用UTF8-Encoding作为passhash,并在连接字符串中声明。我对我的.NET的programms的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有很多不仅仅是说在这种情况下:在你postgresql.conf文件

syntax error at $2 

查找log_destination。记录在那里定义。
More about where to log in the manual here.


您可能需要简化/提高你的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。 否则,如果底层表更改它将以意想不到的方式破坏。

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

+0

你的号码不是解决这个难题。你能告诉我在哪里可以找到那些日志吗?我对postgre很新... – Husky110 2012-04-21 19:22:25

+0

@ Husky110:我加了一点我的答案。 – 2012-04-21 19:29:20

+0

感谢您的时间,但问题是,该功能本身的作品完美。在我看来,这个问题位于程序代码内部的某处,因为当我从编辑器运行它时,它的工作非常完美。我知道insert-targetlist的问题,我使用p作为前缀以避免变量和collumns之间的冲突。 – Husky110 2012-04-21 20:05:32