2012-04-21 79 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