1. 程式人生 > >PostgreSQL安裝及空間資料

PostgreSQL安裝及空間資料

Npgsql: 使用者的手冊

Lastupdate: $Date: 2009/12/20 02:33:47 $ by $Author: fxjr $

Category:External documentation

IntendedAudience: Npgsql Users

1. What is Npgsql?

是一個.net的資料提供者為postgresql的資料庫伺服器

它允許一個.net客戶端應用程式(控制檯,WinForms,ASP的。網路、網路服務…)傳送和接收資料與postgresql的伺服器。它正在積極開發基於指南規定在.net文件。

2. How to get and compile Npgsql 如何獲得和編譯Npgsql

2.1 Binary package  二進位制包

你可以下載Npgsql編譯為MS . 在裡面編寫.net的專案。

這個包裹裡,你會發現下面的目錄的佈局。

Npgsql/bin/docs- Documentation

Npgsql/bin/docs/apidocs- API Documentation

Npgsql/bin/ms1.1- Npgsql compiled for MS.Net 1.1

Npgsql/bin/mono- Npgsql compiled for Mono

As soonas Npgsql is released on other platforms/versions, they will be addedaccordingly to this layout.

2.2 Installing binary package 安裝二進位制包

為了查詢到。net執行時,檔案Npgsql.dll必須放置在你的應用程式目錄——除非你指定另一個目錄作為通往私營成分通過一個配置檔案(使用探測單元)。請看看。net除有關如何執行(位於)總成,被載入。確切地說,前面可以稱為” 通往私人元件"

在ASP。網路和網路服務的應用程式中,必須有一個叫做“bin”的應用與ASP.net目錄. 舉例來說,如果應用程式目錄被稱為“ASPNETApplication”,然後Npgsql.dll和Mono.Security.dll必須放置在“ASPNETApplication \bin”的目錄. 如果這些檔案是不正確的目錄,你可以看到編譯器生成錯誤程式碼,使用Npgsql類。

或者,你可以把Npgsql裝配在解決。自從版本0.4,Npgsql強烈簽字——這意味著你可以用“gacutil "安裝它。

下列命令:

 gacutil - Npgsql.dll

請參閱“安裝裝配在全球快取彙編”部分的單據MSDN來獲得更多資訊.利用gac的意義,你應該充分理解,沿著這條路。

  注意,放置在……要求Npgsql設計時間支援.net視覺化工作室。

  (Npgsql編制單聲道不需要Mono.Security.dll作為已經融入單聲道執行。)

  一旦你拷貝或設定元件,你準備去試試這個例子——跳轉到section 3.

2.3 Getting Npgsql from CVS  獲得Npgsql到CVS

讓Npgsql到CVS,使用下列資料儲存在你的客戶資訊

Server:cvs.pgfoundry.org

Repository:/cvsroot/npgsql

Modulename: Npgsql2

User:anonymous

Password:

If youare using CVS from a command line, use this command:

cvs -d:pserver:[email protected]:/cvsroot/npgsql login

Hit theEnter key when prompted for a password (none required):

cvs -d:pserver:[email protected]:/cvsroot/npgsql checkout Npgsql2

The codewill begin transferring:

$ cvs -d:pserver:[email protected]:/cvsroot/npgsql login

Logging in to:pserver:[email protected]:2401/cvsroot/npgsql

CVS password:

$ cvs -d:pserver:[email protected]:/cvsroot/npgsql co Npgsql2

cvs checkout:Updating Npgsql2

cvs checkout:Updating Npgsql2/admin

UNpgsql2/admin/release.pl

cvs checkout:Updating Npgsql/docs

UNpgsql2/docs/Npgsql.zargo

UNpgsql2/docs/NpgsqlConnectionStateMachine.png

UNpgsql2/docs/SuggestedReadings.htm

...

2.4 Compiling Npgsql  編譯Npgsql

官方支援Npgsql編制方法是0.86版本. 版本0.86是必要的,因為它已經支援編譯顆衛星資源總成。

僅僅從Npgsql /src/ Npgsql資料夾。它將建立一個資料夾名為“build”,看到了“build / ms”資料夾中產生的元件。

我們也有專案檔案為MonoDevelop、視覺工作室網路和視覺化工作室.net2008年。

2.5 Running Npgsql Unit tests  Npgsql執行單元測試

為了能夠跑nunit測試,你必須首先設定你的測試資料庫。

首先,建立一個數據庫稱為npgsql_tests:

createdbnpgsql_tests

再來,建立一個使用者稱為npgsql_tests與密碼:

createuser -NPnpgsql_tests

現在,執行指令碼加表、功能、資料等。這些指令碼是位於testsuite / noninteractive資料夾。

nUnit執行測試,簡單地跑。

3. Npgsql Usage  Npgsql用法

這部分解釋了Npgsql使用.net應用程式中(視窗或net)。如果你是一個有經驗的資料訪問應用程式中使用Sql伺服器、OleDB或ODBC網路供應商,你會發現Npgsql與其非常相似,在很多方面同樣或具有更強的魯棒性,並由一個活躍的社群。

注:Npgsql仍處於發展階段。只會顯示當前支援特徵。作為Npgsql日趨成熟,會有更多的功能。

Adding required namespaces to your source file  新增到原始檔要求的名稱空間

首先,要獲得到Npgsql物件(如下)。Intellisense在.net視覺化工作室),需要指示編譯器使用Npgsql名稱空間。當你操縱資料反演,課程體系Npgsql…資料還將被呼叫。在c#,加上這個指令到適當的網頁或類:

using System.Data;

using Npgsql;

如果你正在使用ASP.NET,你可能需要新增下列程式碼在你的ASPX頁。

<%@ Assemblyname="System.Data" %>

<%@ Assemblyname="Npgsql" %>

Establishing a connection  建立連線

Toestablish a connection to a server located at IP 127.0.0.1, port 5432, as user"joe", with password "secret", on database"joedata", open NpgsqlConnection with the following connectionstring:

建立一個連線到伺服器的IP 127.0.0.1,埠號:5432 使用者“joe”, 密碼資料庫” secret”,開啟NpgsqlConnection 下面的連線字串:

using System;

using System.Data;

using Npgsql;

public classNpgsqlUserManual

{

  public static void Main(String[] args)

  {

    NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Port=5432;User Id=joe;Password=secret;Database=joedata;");

    conn.Open();

    conn.Close();

  }

}

Connection String parameters  連線字串引數

  當建立連線,NpgsqlConnection接受許多引數改變其行為。這裡是目前已有的引數可以修改:(到NpgsqlConnection資料來源)。

  [本主題是字串用來連線到一個postgresql的資料庫。

有效的價值觀是:

ServerAddress/name  postgresql的伺服器連線到ProtocolProtocol版本使用,而不是自動的; DatabaseDatabase整數2或3名。預設的使用者名稱如果不指定使用者名稱SecuritySet IdUser綜合使用windows綜合安全. 預設為文字PasswordPassword =false 認證SSLTrue或false。控制是否嘗試一個安全的聯絡。預設Pooling=false  true或false 。控制是否連線池中使用。真實大小的預設= MinPoolSizeMin 連線池。敏油藏規模,如果使用者指定,會使NpgsqlConnection pre-allocate指定數量的連線的伺服器。預設的:1 MaxPoolSizeMax連線池的大小。混合時將被處理掉的連線池的返回包含超過這個數字池的連線。20 EncodingObsolete違約。總是返回字串"Unicode”,靜靜地忽視試圖把它。TimeoutTime等待連線開啟,在幾秒鐘。預設是15人。CommandTimeoutTime等待命令執行之前完成丟擲一個異常。在幾秒鐘內。預設是20。Sslmode ssl連線控制模式。可以是下列之一:PreferIf是可能的,經SLL SSL連線將被使用。RequireIf SSL連線是不能成立的,是一個例外。AllowNot支援;沒有SSL連線。DisableNo SSL連線。預設值是“關閉”。如果Npgsql SyncNotificationSpecifies應該使用同步通知SearchPathChanges搜尋路徑來指定和公共模式。. Preload Reader

如果被設定為true(預設值是“false”),這導致datareaders裝載之前,在整體ExecuteReader回報。這個結果在較少的效能(特別是在非常大,在這種情況下,recordsets效能可能無法忍受的水平),但是是一種選項來掩蓋獨特潛能backwards-compatibility問題Npgsql以前的版本。

根據ADO . 網路文件,而一個IDataReader是開啟IDbConnection用來獲取是“忙”,不能用於其他操作(幾個檔案的例外)。Npgsql執行這個規則,因此而開放的NpgsqlDataReader大多數其他的操作NpgsqlConnection用來獲得它會導致一個InvalidOperationException(Npgsql鬆弛的規則允許你使用一個連線,如果一個NpgsqlDataReader一直讀到最後,它的產生(s),即使它沒有被關閉,因為這時不再使用任何資源的連線.

Npgsql先前使用者能夠完全忽略了這條規則。這完全是一個副作用的內部實施等問題,並嚴格來說一直支援(因為它總是違反ADO . 網路規範),但是你應該會一點點安慰,忽然發現以前工作的程式碼被打破了。因此,如果你找到一個問題,這種改變,你可以使用這個connection-string選擇回到以前的行為。

如果你確實需要使用,應該這樣做作為權宜之計定價之前程式碼的問題,有兩個原因:

1.    效能,特別是可沒有這個選項要好得多。

2.    這樣的程式碼將會失敗,你應該在任何時候想擴大到支援不同的資料提供者。

利用擴充套件的型別

此選項會影響DataAdaptors是否使用.net體系期望…貨期的型別或Npgsql日期和時間,如NpgsqlTimeStamp型別具有的功能和範圍的System.DateTime。要麼選項允許的型別和系統Npgsql被使用,但如果設定為true DataAdaptors期望能通過特定的Npgsql型別的問題,而如果設定為false,他們將預期System.DateTime

這個選項是實驗性的,可望其影響將減少或刪除,在以後的版本。

預設值為"false".

相容性

這個版本是將其作為一個簡單的處理方法變化來增加更多突破和連線字串選項。它以一種形式的版本號(a.b[[c.d])。改變現有的程式碼將會休息,在可能的情況下,複製行為的前的版本號。第一個這樣的版本是2.0.2.1,所以“2.0.2”不會有新的行為。

Version

Behaviour

2.0.2

1.    如果欄位名是沒有找到, GetOrdinal將返回- 1。

2.    GetOrdinal是kana-width靈敏

2.0.2.1

1.    如果欄位名是沒有找到, GetOrdinal必將IndexOutOfRangeException。

2.    GetOrdinal是kana-width遲鈍。

Using NpgsqlCommand to add a row in a table  使用NpgsqlCommand在表裡新增行

前面的例子不做任何有用的。它僅僅是連線到資料庫斷開連線。如果有一個錯誤,一個NpgsqlException被丟擲。現在,假設你有一個表稱為“表”兩大領域,“fielda”和“fieldb”,兩種型別為int。如果你想插入元組(1):1)在這張表裡,你可以把插入語句。using System;

using System.Data;

using Npgsql;

public staticclass NpgsqlUserManual

{

  public static void Main(String[] args)

  {

    NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Port=5432;User Id=joe;Password=secret;Database=joedata;");

    conn.Open();

    NpgsqlCommand command = newNpgsqlCommand("insert into table1 values(1, 1)", conn);

    Int32 rowsaffected;

    try

    {

      rowsaffected = command.ExecuteNonQuery();

      Console.WriteLine("It was added {0}lines in table table1", rowsaffected);

    }

    finally

    {

      conn.Close();

    }

  }

}

 ExecuteNonQuery()是適合插入、更新查詢,因為它返回整數表示的受上次操作。

Getting a single result value using the NpgsqlCommand.ExecuteScalar()method   

獲得一個結果值使用NpgsqlCommand.ExecuteScalar()方法

在某些情況下,你只需要找回單值(標量),從功能。使用ExecuteScalar()方法,對一個指令物件:

using System;

using System.Data;

using Npgsql;

public staticclass NpgsqlUserManual

{

  public static void Main(String[] args)

  {

    NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Port=5432;UserId=joe;Password=secret;Database=joedata;");

    conn.Open();

    NpgsqlCommand command = new NpgsqlCommand("selectversion()", conn);

    String serverversion;

    try

    {

      serverversion =(String)command.ExecuteScalar();

      Console.WriteLine("PostgreSQL serverversion: {0}", serverversion);

    }

    finally

    {

      conn.Close();

    }

  }

}

你也可以使用ExecuteScalar再次對查詢欄位,如“select count(*) from table1”。然而,當呼叫函式返回的一套一個或多個記錄,只有第一個專欄的第一個條目返回(DataSet.Tables[0]],[[0 .Rows 0])。一般來說,有任何查詢返回的值應該被稱為Command.ExecuteScalar。

Getting a full result set with NpgsqlCommand.ExecuteReader() method andNpgsqlDataReader

得到結果集NpgsqlCommand.ExecuteReader()方法和NpgsqlDataReader

有幾種方法可以返回recordsets與Npgsql。當你想通過一個SQL語句是命令文字和存取的memory-efficent DataReader,使用ExecuteReader()方法的NpgsqlCommand物件:using System;

using System.Data;

using Npgsql;

public staticclass NpgsqlUserManual

{

  public static void Main(String[] args)

  {

    NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Port=5432;UserId=joe;Password=secret;Database=joedata;");

    conn.Open();

    NpgsqlCommand command = newNpgsqlCommand("select * from tablea", conn);

    try

    {

NpgsqlDataReader dr = command.ExecuteReader();

while(dr.Read())

{

  __for (i = 0;i < dr.FieldCount; i++)

  __{

 ___Console.Write("{0} \t", dr[i]);

  __}

 __Console.WriteLine();

}

    }

    finally

    {

      conn.Close();

    }

  }

}

 Note that you can 'daisy chain' selectstatements in a command object's commandtext to retrieve more than one recordset: "select * from tablea; select * from tableb"

Using parameters in a query  利用引數查詢

讓你dynamcially引數插入到SQL查詢的價值觀的執行時間。一般說來,引數約束的最好辦法是建立動態SQL語句在你的程式碼。其他的方法,如基本字串連線,越來越少的魯棒性和可vulerable到SQL注入攻擊。加到你的SQL查詢字串引數的paramter名字的字首,以“:”。下面的例子使用了引數(see ":value1")。

using System;

using System.Data;

using Npgsql;

public staticclass NpgsqlUserManual

{

    public static void Main(String[] args)

    {

        using(NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Port=5432;UserId=joe;Password=secret;Database=joedata;"))

        {

            conn.Open();

            // Declare the parameter in thequery string

            using(NpgsqlCommand command = newNpgsqlCommand("select * from tablea where column1 = :value1", conn))

            {

                // Now add the parameter to theparameter collection of the command specifying its type.

                command.Parameters.Add(newNpgsqlParameter("value1", NpgsqlDbType.Integer));

                // Now, add a value to it andlater execute the command as usual.

                command.Parameters[0].Value =4;

                using(NpgsqlDataReader dr =command.ExecuteReader())

                {

                    while(dr.Read())

                    {

                        for (i = 0; i <dr.FieldCount; i++)

                        {

                           Console.Write("{0} \t", dr[i]);

                        }

                        Console.WriteLine();

                    }

                }

            }

        }

    }

}

您也可以發一個引數查詢到伺服器使用NpgsqlParamenter和NpgsqlParamenterCollection物體。)這個程式碼假定一個表稱為“稱至少有一個專欄”命名為" column1”式的int4。

Using prepared statements  使用準備報告

在準備方法讓你優化效能的常用的疑問。Prepare ()的主要“快取"查詢計劃,這樣就可以用在隨後的電話。(注意:這個功能才可在伺服器7.3 +版本。如果你叫它在一個伺服器不支援它,Npgsql會靜靜地忽視它。)簡單地叫準備()方法的NpgsqlCommand前查詢過程。

using System;

using System.Data;

using Npgsql;

public staticclass NpgsqlUserManual

{

    public static void Main(String[] args)

    {

        using(NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Port=5432;UserId=joe;Password=secret;Database=joedata;"))

        {

            conn.Open();

            // Declare the parameter in thequery string

            using(NpgsqlCommand command = newNpgsqlCommand("select * from tablea where column1 = :column1", conn))

            {

                // Now add the parameter to theparameter collection of the command specifying its type.

                command.Parameters.Add(newNpgsqlParameter("column1", NpgsqlDbType.Integer);

                // Now, prepare the statement.

                command.Prepare();

                // Now, add a value to it andlater execute the command as usual.

                command.Parameters[0].Value =4;

                using(NpgsqlDataReader dr =command.ExecuteReader())

                {

                    while(dr.Read())

                    {

                        for (i = 0; i <dr.FieldCount; i++)

                        {

                            Console.Write("{0}\t", dr[i]);

                        }

                        Console.WriteLine();

                    }

                }

            }

        }

    }

}

這個程式碼假定一個表稱為“稱至少有一個專欄”命名為" column1”式的int4。

Function calling  函式呼叫

呼叫函式, 把CommandType財產的CommandType NpgsqlCommand物件.StoredProcedure和傳球的名字,你想叫作為函式的返回查詢字串(CommandText property)。

using System;

using System.Data;

using Npgsql;

//下面的例子使用了funcC函式定義()

// 建立 function funcC() 返回整數'

// select count(*)from tablea;

// ' language'sql';

//注:返回型別的選擇(*)的改變,從int4到int8在7.3 +版本。使用這個函式

//在一個7.2伺服器,改變了對int4從int8返回型別。

public staticclass NpgsqlUserManual

{

  public static void Main(String[] args)

  {

    NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Port=5432;UserId=joe;Password=secret;Database=joedata;");

    conn.Open();

    try

    {

        NpgsqlCommand command = newNpgsqlCommand("funcC", conn);

        command.CommandType =CommandType.StoredProcedure;

        Object result =command.ExecuteScalar();

        Console.WriteLine(result);

    }

    finally

    {

      conn.Close();

    }

  }

}

新增引數到postgresql的功能類似於我們先前的例子。然而,當指定返回字串時,你可以排除引數的名字。使用函式的名稱。

using System;

using System.Data;

using Npgsql;

//下面的例子使用了funcC函式

// create functionfuncC(int4) returns int8 as '

// select count(*)from tablea where field_int4 = $1;

// ' language'sql';

public staticclass NpgsqlUserManual

{

  public static void Main(String[] args)

  {

    NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Port=5432;UserId=joe;Password=secret;Database=joedata;");

    conn.Open();

    try

    {

        NpgsqlCommand command = newNpgsqlCommand("funcC", conn);

        command.CommandType =CommandType.StoredProcedure;

        __command.Parameters.Add(newNpgsqlParameter());

        command.Parameters[0].NpgsqlDbType =NpgsqlDbType.Integer;

        command.Parameters[0].Value = 4;

        Object result =command.ExecuteScalar();

        Console.WriteLine(result);

    }

    finally

    {

      conn.Close();

    }

  }

}

這個程式碼假定一個表稱為“稱至少有一場”,被稱為“field_int4”式的int4。

Getting full results in a DataSet object: Using refcursors  結果得到充分的資料物件:使用 refcursors

Refcursors是最有效的方法來建造功能,返回的結果集Postgres給客戶端。使用refcursors單一功能,可以返回結果查詢到客戶端在一個單一的來回票。大多數Npgsql開發商知道refcursors非常容易使用,一旦你掌握了基本的語法。這兩種結果集樣本返回從功能使用refcursors。Npgsql一致的支援refcursor,你可以得到很多的結果集,而不必擔心內部refcursorPostgres的運作。

考慮以下refcursor-based功能:

CREATE OR REPLACEFUNCTION testrefcursor(int4) RETURNS SETOF refcursor AS

'DECLARE

  ref1 refcursor;

  ref2 refcursor;

  ref3 refcursor;

BEGIN

OPEN ref1 FOR

 SELECT * FROM table1;

RETURN NEXT ref1;

OPEN ref2 FOR

 SELECT * FROM table2;

RETURN next ref2;

OPEN ref3 FOREXECUTE

 'SELECT * FROM table3 WHERE keyfield = ' ||$1;

RETURN next ref3;

RETURN;

END;'

LANGUAGE plpgsql;

這個函式將返回三個選擇語句結果。值得注意的是,最後選擇宣告動態建立伺服器上。

現在,這些功能和檢索資料使用DataReader時,你應該用下面的程式碼:

using System;

using System.Data;

using Npgsql;

using NpgsqlTypes;

public class c

{

    public static void Main(String[] args)

    {

        NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Initial Catalog=eeeeee;Userid=npgsql_tests;password=npgsql_tests;");

        conn.Open();

        NpgsqlTransaction t =conn.BeginTransaction();         

        NpgsqlCommand command = newNpgsqlCommand("testrefcursor", conn);

        command.CommandType =CommandType.StoredProcedure;

        NpgsqlDataReader dr =command.ExecuteReader();

        while(dr.Read())

        {

            Console.WriteLine(dr.GetValue(0));

        }

        dr.NextResult();

        while(dr.Read())

        {

            Console.WriteLine(dr.GetValue(0));

        }

        dr.Close();

        t.Commit();

        conn.Close();

    }

}

或者,你可以檢索結果變成一個數據物件

using System;

using System.Data;

using Npgsql;

using NpgsqlTypes;

public class c

{

    public static void Main(String[] args)

    {

        DataSet myDS;

        NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Initial Catalog=eeeeee;Userid=npgsql_tests;password=npgsql_tests;");

        conn.Open();

        NpgsqlTransaction t =conn.BeginTransaction();         

        NpgsqlCommand command = newNpgsqlCommand("testrefcursor", conn);

        command.CommandType = CommandType.StoredProcedure;

        con.Open();

        NpgsqlDataAdapter da = newNpgsqlDataAdapter(command);

        da.Fill(myDS);

        t.Commit();

        conn.Close();

    }

}

就是這樣!”。最後一件事值得一提的是,你必須用一種交易為了使這項工作。這是有必要的, 預防指標返回通過refcursor功能關閉後的implicity交易完成,(你做的呼叫函式)。

如果你在你的函式引數,只給函式的名字和新增引數返回財產的NpgsqlCommand引數採集像往常一樣。Npgsql管理你正確的引數約束。

Using output parameters in a query  採用輸出引數在一個查詢

輸出引數,可以用Npgsql。注意Npgsql“simulates”輸出引數分解了第一個結果集執行查詢和翻譯它輸出引數值。這可以在兩個方面:一是對映。一個對映解析 試配以列名返回到一個引數產生同樣的名字。如果找到匹配的,只有輸出引數有比賽將被更新。如果一個地圖是沒有找到,輸出引數進行更新,以他們新增到命令引數採集。該對映是自動的。在分析產生,Npgsql試圖找到了一個相配的。輸出和InputOutput引數方向都支援。

using System;

using System.Data;

using Npgsql;

public staticclass NpgsqlUserManual

{

    public static void Main(String[] args)

    {

        NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Port=5432;UserId=joe;Password=secret;Database=joedata;");

        conn.Open();

        // Send a query to backend.

        NpgsqlCommand command = newNpgsqlCommand("select * from tablea where column1 = 2", conn);

        // Now declare an output parameter toreceive the first column of the tablea.

        NpgsqlParameter firstColumn = newNpgsqlParameter("firstcolumn", NpgsqlDbType.Integer);

        firstColumn.Direction =ParameterDirection.Output;

        command.Parameters.Add(firstColumn);

        try

        {

            command.ExecuteNonQuery();

            // Now, the firstcolumn parameterwill have the value of the first column of the resultset.

           Console.WriteLine(firstColumn.Value);

        }

        finally

        {

            conn.Close();

        }

    }

}

Working with .NET Datasets   工作和。net的資料集

Npgsql讓你相依的改變.net的資料物件到資料庫。下面的例子演示了插入一個記錄到的資料集,緊隨其後的是一個叫更新相關資料庫:

// This methodexpects the following table in the backend:

//

//_create tabletableb(field_int2 int2, field_timestamp timestamp, field_numeric numeric);

//

//_

voidAddWithDataSet(NpgsqlConnection conn)

{_

conn.Open();

DataSet ds = newDataSet();

NpgsqlDataAdapterda = new NpgsqlDataAdapter("select * from tableb", conn);

da.InsertCommand =new NpgsqlCommand("insert into tableb(field_int2, field_timestamp,field_numeric) " + " values (:a, :b, :c)", conn);

da.InsertCommand.Parameters.Add(newNpgsqlParameter("a", NpgsqlDbType.Smallint));

da.InsertCommand.Parameters.Add(newNpgsqlParameter("b", NpgsqlDbType.Timestamp));

da.InsertCommand.Parameters.Add(newNpgsqlParameter("c", NpgsqlDbType.Numeric));

da.InsertCommand.Parameters[0].Direction= ParameterDirection.Input;

da.InsertCommand.Parameters[1].Direction= ParameterDirection.Input;

da.InsertCommand.Parameters[2].Direction= ParameterDirection.Input;

da.InsertCommand.Parameters[0].SourceColumn= "field_int2";

da.InsertCommand.Parameters[1].SourceColumn= "field_timestamp";

da.InsertCommand.Parameters[2].SourceColumn= "field_numeric";

da.Fill(ds);

DataTable dt =ds.Tables[0];

DataRow dr =dt.NewRow();

dr["field_int2"]= 4;

dr["field_timestamp"]= new DateTime(2003, 03, 03, 14, 0, 0);

dr["field_numeric"]= 7.3M;

dt.Rows.Add(dr);

DataSet ds2 =ds.GetChanges();

da.Update(ds2);

ds.Merge(ds2);

ds.AcceptChanges();

}

Working with strongly typed datasets  處理資料工作

這個例子演示了使用一種強烈的輸入的資料所產生的將來預留的。開始時,我們需要一個將來預留的檔案specifing有效的方案。你可以生成這個檔案,或者你可以用一個將來預留的工具來產生。為了讓NpgsqlDataAdapter產生將來預留,你需要供應和XML檔案中,XML檔案的推理的允許XML格式。

public voidGenerateXmlFromDataSet(NpgsqlConnection conn)

{

conn.Open();

NpgsqlDataAdapterda = new NpgsqlDataAdapter("select * from tablea", conn);

DataSet ds = newDataSet();

da.Fill(ds);

ds.WriteXml("StrongDataSetFeed.xml");

}

這個例子的結果在一個檔案中,看起來相似。

<?xmlversion="1.0" standalone="yes"?>

<NewDataSet>

  <Table>

    <field_serial>1</field_serial>

    <field_text>Randomtext</field_text>

  </Table>

  <Table>

    <field_serial>2</field_serial>

    <field_int4>4</field_int4>

  </Table>

  <Table>

    <field_serial>3</field_serial>

    <field_int8>8</field_int8>

  </Table>

  <Table>

    <field_serial>4</field_serial>

    <field_bool>true</field_bool>

  </Table>

  <Table>

    <field_serial>5</field_serial>

    <field_text>Text with ' singlequote</field_text>

  </Table>

</NewDataSet>

下列命令用檔案生成將來預留的

xsdStrongDataSetFeed.xml

XSD willproduce an XML schema in which all types are specified as string. As aconsequence, we need to change the XSD to specify the correct types, resultingin an XSD file similar to:

<?xmlversion="1.0" encoding="utf-8"?>

<xs:schemaid="NewDataSet" xmlns=""xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

  <xs:element name="NewDataSet"msdata:IsDataSet="true" msdata:Locale="pt-BR">

    <xs:complexType>

      <xs:choicemaxOccurs="unbounded">

        <xs:elementname="Table">

          <xs:complexType>

            <xs:sequence>

              <xs:elementname="field_serial" type="xs:int" minOccurs="0"/>

              <xs:elementname="field_text" type="xs:string" minOccurs="0"/>

              <xs:elementname="field_int4" type="xs:int" minOccurs="0"/>

              <xs:elementname="field_int8" type="xs:long" minOccurs="0"/>

              <xs:elementname="field_bool" type="xs:boolean" minOccurs="0"/>

            </xs:sequence>

          </xs:complexType>

        </xs:element>

      </xs:choice>

    </xs:complexType>

  </xs:element>

</xs:schema>

鑑於上述檔案,下面的指令生成一個強烈的輸入資料:

xsdStrongDataSetFeed.xsd /dataset

這個指令生成一個檔案的整理成一個裝配工作的資料。產品廣泛應用於下面的例子。

using System;

using Npgsql;

public class t

{

   public static void Main(String[] args)

   {

      NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Port=5432;UserId=joe;Password=secret;Database=joedata;");

      conn.Open();

      NpgsqlDataAdapter da = newNpgsqlDataAdapter("Select * from tablea", conn);

      NewDataSet n = new NewDataSet();

      da.Fill(n);

      foreach (NewDataSet._TableRow tr inn._Table)

      {

        Console.WriteLine(tr.field_serial);

      }

   }

}

Working with binary data and bytea datatype  工作 二進位制資料和bytea資料型別

這個樣品需要一個檔名作為一個引數,將其內容到一張表被稱為“tableByteA”。表格包含一場名為“field_bytea”式的bytea和一場名為“field_serial”型系列。接下來,它的內容和寫作領域中一個新的檔案字尾"database".

表圖式理論: create table tableBytea(field_serial serial, field_bytea bytea)

using System;

using System.Data;

using Npgsql;

using System.IO;

public class t

{

  public static void Main(String[] args)

  {

    //NpgsqlEventLog.Level = LogLevel.Debug;

    //NpgsqlEventLog.LogName ="NpgsqlTests.LogFile";

    NpgsqlConnection conn = newNpgsqlConnection("server=localhost;userid=npgsql_tests;password=npgsql_tests");

    conn.Open();

    FileStream fs = new FileStream(args[0],FileMode.Open, FileAccess.Read);

    BinaryReader br = new BinaryReader(newBufferedStream(fs));

    Byte[] bytes =br.ReadBytes((Int32)fs.Length);

    Console.WriteLine(fs.Length);

    br.Close();

    fs.Close();

    NpgsqlCommand command = newNpgsqlCommand("insert into tableBytea(field_bytea)values(:bytesData)", conn);

    NpgsqlParameter param = newNpgsqlParameter(":bytesData", NpgsqlDbType.Bytea);

    param.Value = bytes;

    command.Parameters.Add(param);

    command.ExecuteNonQuery();

    command = new NpgsqlCommand("selectfield_bytea from tableBytea where field_serial = (select max(selectfield_serial) from tableBytea);", conn);

    Byte[] result =(Byte[])command.ExecuteScalar();

    fs = new FileStream(args[0] +"database", FileMode.Create, FileAccess.Write);

    BinaryWriter bw = new BinaryWriter(newBufferedStream(fs));

    bw.Write(result);

    bw.Flush();

    fs.Close();

    bw.Close();__

    conn.Close();

  }

}

Working with large object support 工作對大物件支援使用

這樣品是幾乎相同的bytea以上程式碼。它儲存檔案檢索postgresql,然後再刪除。例如用bytea示例檔案,寫著“database “字尾。

using System;

using System.Data;

using Npgsql;

using NpgsqlTypes;

using System.IO;

public class c

{

    public static void Main(String[] args)

    {

        NpgsqlConnection newconn = newNpgsqlConnection("server=localhost;userid=npgsql_tests;password=npgsql_tests");

        newcon.Open();

        NpgsqlTransaction t =newcon.BeginTransaction();

        LargeObjectManager lbm = newLargeObjectManager(newcon);

        int noid =lbm.Create(LargeObjectManager.READWRITE);

        LargeObject lo =  lbm.Open(noid,LargeObjectManager.READWRITE);

        FileStream fs = File.OpenRead(args[0]);

        byte[] buf = new byte[fs.Length];

        fs.Read(buf,0,(int)fs.Length);

        lo.Write(buf);

        lo.Close();

        t.Commit();

        t = newcon.BeginTransaction();

        lo = lbm.Open(noid,LargeObjectManager.READWRITE);

        FileStream fsout =File.OpenWrite(args[0] + "database");

        buf = lo.Read(lo.Size());

        fsout.Write(buf, 0, (int)lo.Size());

        fsout.Flush();

        fsout.Close();

        lo.Close();

        t.Commit();

        DeleteLargeObject(noid);

        Console.WriteLine("noid:{0}", noid);

        newcon.Close();

    }

    public static void DeleteLargeObject(Int32noid)

    {

        NpgsqlConnection conn = newNpgsqlConnection("server=localhost;userid=npgsql_tests;password=npgsql_tests");

        newcon.Open();

        NpgsqlTransaction t =newcon.BeginTransaction();

        LargeObjectManager lbm = newLargeObjectManager(newcon);

        lbm.Delete(noid);

        t.Commit();

        newcon.Close();

    }

}

另一個例子是由mirek(mirek在mascort點COM點PL),大物件支援使用到從資料庫中的影象顯示在窗體上的客戶。

using System;

using Npgsql;

using NpgsqlTypes;

usingSystem.Drawing;

using System.IO;

//metod whos 影象連線到資料庫

public inttakeOID(int id)

{

    //這是一個metodwhos連線到資料庫,並返回影象oid

    BazySQL pir = newBazySQL(Login.DaneUzera[8]);

    string pytanko = String.Format("selectrysunek from k_rysunki where idtowaru = " + idtowaru.ToString());

    string[] wartosci =pir.OddajSelectArray(pytanko);

    int liczba =int.Parse(wartosci[0].ToString());

    return liczba;

}

//從資料庫轉換到影象的型別

public ImagepobierzRysunek(int idtowaru)

{

    NpgsqlConnection Polacz = newNpgsqlConnection();

    Polacz.ConnectionString =Login.DaneUzera[8].ToString();  //itsmetod whos return connection string

    Polacz.Open();

    NpgsqlTransaction t =Polacz.BeginTransaction();

    LargeObjectManager lbm = newLargeObjectManager(Polacz);

    LargeObject lo =lbm.Open(takeOID(idtowaru),LargeObjectManager.READWRITE); //take picture oidfrom metod takeOID

    byte[] buf = new byte[lo.Size()];

    buf = lo.Read(lo.Size());

    MemoryStream ms = new MemoryStream();

    ms.Write(buf,0,lo.Size());

    lo.Close();

    t.Commit();

    Polacz.Close();

    Polacz.Dispose();

    Image zdjecie = Image.FromStream(ms);

    return zdjecie;

}

//接著我用這個方法

pictureBox1.Image= Image pobierzRysunek(1);

Retrieving last inserted id on a table with serial values   找回最後的標識一個表中的序列值

這個例子是由喬希在論壇回答一使用者問題。假定本程式碼表和功能在你npgsql資料庫中:

create tabletest_seq (field_serial serial, test_text text);

 CREATE OR REPLACE FUNCTIONins_seq("varchar")

        RETURNS test_seq AS

        'insert into test_seq (test_text)values ($1);

        select * from test_seq where test_text= $1'

        LANGUAGE 'sql' VOLATILE;

這是程式碼:

using System;

using System.Data;

using Npgsql;

using NpgsqlTypes;

public class c

{

    public static void Main(String[] args)

    {

        //NpgsqlEventLog.Level =LogLevel.Debug;

        //NpgsqlEventLog.LogName ="NpgsqlTests.LogFile";

        //NpgsqlEventLog.EchoMessages = true;

        NpgsqlConnection conn = newNpgsqlConnection("Server=127.0.0.1;Userid=npgsql_tests;password=npgsql_tests;");

        using (NpgsqlDataAdapter adapter = newNpgsqlDataAdapter("select * from test_seq", conn))

        {

            DataTable table = new DataTable();

            adapter.Fill(table);

            adapter.InsertCommand = newNpgsqlCommand("ins_seq", adapter.SelectCommand.Connection);

           adapter.InsertCommand.Parameters.Add("foo",NpgsqlTypes.NpgsqlDbType.Varchar, 100, "test_text");

            adapter.InsertCommand.CommandType =CommandType.StoredProcedure;

            DataRow row = table.NewRow();

            row["test_text"] ="asdfqwert";

            table.Rows.Add(row);

            adapter.Update(table);

            foreach (DataRow rowItem in table.Rows)

            {

                Console.WriteLine("key{0}, value {1}", rowItem[0], rowItem[1]);

            }

            Console.ReadLine();

        }

    }

}

Cancelling a command in progress  取消命令

npgsql可以讓伺服器取消命令。為此,我們取消npgsqlcommand的方法。注意另一個執行緒必須處理的請求作為主要的執行緒將堵塞等命令。此外,主要的執行緒將異常結果的使用者登出。(錯誤程式碼57014。)看下面的程式碼演示了這個技術:

using System;

using System.Data;

using Npgsql;

using NpgsqlTypes;

usingSystem.Threading;

public class c

{

//此方法要求下表中後端:

    //

    /*     CREATE OR REPLACE FUNCTION funcwaits() returns integer as

    '

    declare t integer;

    begin

    t := 0;

    while t < 1000000 loop

    t := t + 1;

    end loop;

    return t;

    end;

    '

    */

    static NpgsqlConnection conn = null;

    static NpgsqlCommand command = null;

    public static void Main(String[] args)

    {

        //NpgsqlEventLog.Level =LogLevel.Debug;

        //NpgsqlEventLog.LogName ="NpgsqlTests.LogFile";

        //NpgsqlEventLog.EchoMessages = true;

        try

        {

          conn = new NpgsqlConnection("Server=127.0.0.1;Userid=npgsql_tests;password=npgsql_tests;");

          conn.Open();

          NpgsqlCommand d = newNpgsqlCommand();

          Thread t = new Thread(newThreadStart(CancelRequest));

          command = newNpgsqlCommand("select * from funcwaits()", conn);

          Console.WriteLine("Cancellingcommand...");

          t.Start();

         Console.WriteLine(command.ExecuteScalar());

          conn.Close();

        }

        catch(NpgsqlException e)

        {

                if (e.Code == "57014")

                       Console.WriteLine("Command was cancelled");

        }

    }

    public static void CancelRequest()

    {

        command.Cancel();

        Console.WriteLine("commandcancelled");

    }

}

Working with Notifications   工作與通知

Npgsql允許使用者接受事件基於發出通知伺服器。有兩種方法來獲得notications與Npgsql:同步或不同步。同步通知Npgsql只支援1.0以上。

Asynchronous notifications   非同步通知

這是預設的通報機制在npgsql。它被稱為非同步因為npgsql沒有收到通知在執行,它在伺服器上產生. npgsql收到通知在客戶端互動的伺服器。這種互動實際上發生在Npgsql傳送一個後續的命令,伺服器-這可能由幾秒到幾小時後。在這種情況下,大多數使用者需要積極投票伺服器為了得到及時通知。投票的方式之一,包括通過空指令,如";"

Synchronous notifications  同步通知

從Npgsql 1.0,有支援同步通知。當工作在這種模式下,Npgsql能夠獲得notificaton在它的例項化並交付給客戶。所有這一切都是沒有任何附加的顧客和伺服器之間的互動作用(如上所述)。

重要的通知: 當使用同步通知,在你的通知不能執行命令處理程式的功能。如果你這樣做,你就會落npgsql作線,負責通知的一樣,處理npgsql和後端。如果你想使用任何命令,請建立一個連線,使用它。這不是最好的解決辦法,我們要研究更好的辦法去解決,而不需要一個連線。

這個程式碼與通知是相同的模式:

using System;

using System.Data;

using Npgsql;

using NpgsqlTypes;

usingSystem.Threading;

public class c

{

    public static void Main(String[] args)

    {

        conn = newNpgsqlConnection("Server=127.0.0.1;Userid=npgsql_tests;password=npgsql_tests;");

        conn.Open();

        NpgsqlCommand command = newNpgsqlCommand("listen notifytest;", conn);

        command.ExecuteNonQuery();

        conn.Notification += newNotificationEventHandler(NotificationSupportHelper);

        command = newNpgsqlCommand("notify notifytest;", _conn);

        command.ExecuteNonQuery();

        Console.ReadLine();  // To prevent program termination beforenotification is handled.

    }

    private void NotificationSupportHelper(Objectsender, NpgsqlNotificationEventArgs args)

    {

        // process notification here.

    }

}

這個程式碼宣告一個通知,並有引數傳遞到NotificationSupportHelper方法。

Fast bulk data copy into a table 大量的資料複製到表

批插入大量資料會耗費大量時間。postgresql提供一種選擇,很快的插入資料。它的語法和輸入格式選項已經解釋了在postgresql的拷貝檔案。複製資料從客戶端到需要使用的選項。

在直接拷貝執行時檔案, 你提供的資料進行編碼的使用相同的伺服器。

最簡單的方法是,提供可讀檔案的copyin操作。在建構函式,這份工作就會讀的東西都流到了伺服器。 (提交一份宣告中的文件不同的輸入格式!)

1.    你看SyncNotification =true 的在您的資料庫連線字串。這是抓住任何異常報告在進口以防止顧客和伺服器之間的僵局網路緩衝器。

2.    建立NpgsqCopyIn物件提供資料流輸入資料庫

3.    開始複製操作。工作完畢

4.    如果開始()將丟擲異常,NpgsqlCopyIn.Cancel()取消一項持續的操作和清晰的連接回到準備查詢的狀態。否則你的連線可以呆在複製模式,不能做別的事情。

using System;

using System.Data;

using Npgsql;

public classCopyInExample

{

    public static void Main(String[] args)

    {

        conn = newNpgsqlConnection("Server=127.0.0.1;Userid=npgsql_tests;password=npgsql_tests;SyncNotification=true;");

        conn.Open();

        NpgsqlCommand command = newNpgsqlCommand("COPY myCopyTestTable FROM STDIN", conn);

        NpgsqlCopyIn cin = new NpgsqlCopyIn(command, conn, Console.OpenStandardInput() ); // expecting input in serverencoding!

        try

        {

            cin.Start();

        }

        catch(Exception e)

        {

            try

            {

                cin.Cancel("Undocopy");

            }

            catch(NpgsqlException e2)

            {

                // we should get an error inresponse to our cancel request:

                if( !(""+e2).Contains("Undo copy") )

                {

                    throw newException("Failed to cancel copy: " + e2 + " upon failure:" + e);

            }

            throw e;

        }

    }

}

如果你願意提供的資料從你的應用程式,你可以用正常的輸入流:

1.    你看SyncNotification =true 的在您的資料庫連線字串。這是抓住任何異常報告在進口以防止顧客和伺服器之間的僵局網路緩衝器。  

2.    建立NpgsqCopyIn物件提供資料流輸入資料庫  

3.    開始複製操作。工作完畢

4.    寫資料的格式和編碼成 npgsqlcopyin.copystream

5.    在連線期間不能用於任何其他事情。

6.    叫copystream。close()或npgsqlcopyin。end()完成寫作

7.    取消一項持續的操作和清晰的聯絡,準備回電話查詢狀態NpgsqlCopyIn.Cancel()。

8.    Upon failure callNpgsqlCopyIn.Cancel() to cancel an ongoing operation and clear connection backto Ready For Query state. Otherwise your connection may stay in copy mode,unusable for anything else.

using System;

using System.Data;

using Npgsql;

public classCopyInExample

{

    public static void Main(String[] args)

    {

        conn = newNpgsqlConnection("Server=127.0.0.1;Userid=npgsql_tests;password=npgsql_tests;SyncNotification=true;");

        conn.Open();

        NpgsqlCommand command = newNpgsqlCommand("COPY myCopyTestTable FROM STDIN", conn);

        NpgsqlCopyIn cin = new NpgsqlCopyIn(command, conn );

        Stream inStream =Console.OpenStandardInput();

        Encoding inEncoding =System.Text.Encoding.ASCII;

        Encoding serverEncoding =System.Text.Encoding.BigEndianUnicode; // example assumption

        try

        {

            cin.Start();

            Stream copyInStream =cin.CopyStream;

            byte[] buf = new byte[9];

            int i;

            while( (i =inStream.Read(buf,0,buf.Length)) > 0 )

            {

                buf = System.Text.Convert(inEncoding, serverEncoding, buf, 0, i );

                copyInStream.Write( buf, 0, i);

            }

            copyInStream.Close(); // orcin.End(), if you wish

        }

        catch(Exception e)

        {

            try

            {

                cin.Cancel("Undocopy"); // Sends CopyFail to server

            }

            catch(Exception e2)

            {

                // we should get an error inresponse to our cancel request:

                if( !(""+e2).Contain