VB.NET/C#でPostgreSQLからデータを取得する【Npgsql】

VB.NET/C#

概要

.NET Framework環境でVB.NETやC#からPostgreSQLへ接続し、データを取得する方法についてのメモです。接続方法については「ODBC」による接続や、「Entity Framework Core」による接続などありますが、ここでは「Npgsql」(ADO.NETのデータプロバイダ)による接続方法について試してみます。

今回は以下の環境で試しています。

OSWindows 11
データベースPostgreSQL 16.4
IDEVisual Studio 2022
.NET Framework4.7.2
Npgsql8.0.5

Windowsフォームアプリを作成し、DataGridViewに取得したデータを表示してみます。

Npgsqlの導入

NpgsqlはNugetから入手できます。ソリューションエクスプローラのプロジェクトを選択し、右クリックメニューから「Nugetパッケージの管理(N)…」を選択します。
その後、「Npgsql」を検索し、「インストール」をクリックしインストールします。

プロジェクト 右クリックメニュー
nuget npgsqlインストール

Npgsqlの詳細は公式ホームページを参照してください。

PostgreSQLへの接続

最初にデータベースへ接続します。
接続時に必要な接続文字列を作成するために、接続情報を「NpgsqlConnectionStringBuilder」にセットします。
その後、上記クラスで作成した接続文字列を指定して「NpgsqlConnection」にてデータベースへ接続します。

  • VB.NET
  • C#
'接続情報を設定
Dim sb As New Npgsql.NpgsqlConnectionStringBuilder
With sb
  .Host = "192.168.1.37"      ' ホスト名、IPアドレス
  .Database = "testdb1"       ' データベース名
  .Username = "testuser1"     ' 接続ユーザ名
  .Password = "xxxxxxxxx"     ' パスワード
  .Port = "5432"              ' 接続ポート番号
End With

'データベースへの接続
Using conn As New NpgsqlConnection(sb.ConnectionString)
  conn.Open()

  'データベース接続後にSQL実行

End Using
//接続情報を設定
Npgsql.NpgsqlConnectionStringBuilder sb = new Npgsql.NpgsqlConnectionStringBuilder();
sb.Host = "192.168.1.37";        // ホスト名、IPアドレス
sb.Database = "testdb1";         // データベース名
sb.Username = "testuser1";       // 接続ユーザ名
sb.Password = "xxxxxxxxx";       // パスワード
sb.Port = 5432;                  // 接続ポート番号

//データベースへの接続
using (Npgsql.NpgsqlConnection conn = new Npgsql.NpgsqlConnection(sb.ConnectionString))
{
    conn.Open();

    //データベース接続後にSQL実行

}

NpgsqlConnectionStringBuilderには、主に次表のような値を設定します。

Host接続するデータベースサーバのホスト名やIPアドレス
Database接続するデータベースの名前
Usernameデータベースに接続するユーザ名
Passwordデータベースに接続するユーザのパスワード
Port接続するデータベースサーバのポート番号

設定後、ConnectionStringで接続文字列を取得できますが、今回の例だと以下のような文字列になります。

"Host=192.168.1.37;Database=testdb1;Username=testuser1;Password=xxxxxxxxx;Port=5432"

NpgsqlConnectionStringBuilderを使わず、接続文字列を直接指定してもOKです。
NpgsqlConnectionに取得した接続文字列を渡してインスタンスを生成します。
インスタンスを生成したら、Open()でデータベースに接続します。

SQLコマンドを実行する(SELECT)

データベースに接続したら、SQLコマンドを実行します。
今回はサンプルとして以下のようなテーブル「testtbl」のデータを取得する「SELECT」コマンドを実行してみます。

サンプルデータ

SQLコマンドを実行するために、「NpgsqlCommand」にSQL文とデータベースへの接続を渡します。

  • VB.NET
  • C#
'SQLの実行
Dim sqlStr As String = "SELECT * FROM testtbl ORDER BY id"
Using cmd As New NpgsqlCommand(sqlStr, conn)

    'SQL実行結果の取得

End Using
//SQLの実行
String sqlStr = "SELECT * FROM testtbl ORDER BY id";
using (NpgsqlCommand cmd = new NpgsqlCommand(sqlStr, conn))
{

    //SQL実行結果の取得

}

この例では、「SELECT * FROM testtbl ORDER BY id」というSQLコマンドを実行します。

SQLコマンドの実行結果を取得する

SQLコマンドを実行し、その結果を1行ずつ取得し、DataTableにセットします。
「NpgsqlCommand」の「ExecuteReader()」で「NpgsqlDataReader」を取得します。
その後取得した「NpgsqlDataReader」の「Read()」で1行ずつデータを取得していきます。

  • VB.NET
  • C#
'DateTable初期化
Dim dt As New DataTable("testtbl")
dt.Columns.Add("ID", GetType(String))
dt.Columns.Add("名前", GetType(String))
dt.Columns.Add("電話番号", GetType(String))
dt.Columns.Add("メール", GetType(String))
dt.Columns.Add("点数", GetType(Integer))

              .
              .
              .

'SQL実行結果の取得
Using reader As NpgsqlDataReader = cmd.ExecuteReader()
    '1行ずつ取得
    While (reader.Read())
        '結果をDataTableにセット
        Dim dr As DataRow = dt.NewRow()
        dr.Item("ID") = reader.Item("id")
        dr.Item("名前") = reader.Item("name")
        dr.Item("電話番号") = reader.Item("tel")
        dr.Item("メール") = reader.Item("email")
        dr.Item("点数") = reader.Item("score")
        dt.Rows.Add(dr)
    End While
End Using

'DataGridViewにセット
Me.dgvData.DataSource = dt
//DataTable初期化
DataTable dt = new DataTable("testtbl");
dt.Columns.Add("ID", typeof(String));
dt.Columns.Add("名前", typeof(String));
dt.Columns.Add("電話番号", typeof(String));
dt.Columns.Add("メール", typeof(String));
dt.Columns.Add("点数", typeof(int));

              .
              .
              .

//SQL結果取得
using (NpgsqlDataReader reader = cmd.ExecuteReader())
{
    //1行ずつ取得
    while (reader.Read())
    {
        DataRow dr = dt.NewRow();
        dr["ID"] = reader["id"];
        dr["名前"] = reader["name"];
        dr["電話番号"] = reader["name"];
        dr["メール"] = reader["email"];
        dr["点数"] = reader["score"];
        dt.Rows.Add(dr);
    }
}

//DataGridViewにセット
dgvData.DataSource = dt;

「reader.Read()」で結果がFalseになるまでループし1行ずつデータを取得し、「reader.Item(“列名”)」(C#だと「reader[“列名”]」)で各列のデータを取得しています。
最後に、取得データを格納したDataTableをDataGridView(名称:dgvData)にセットしています。

実際に実行すると以下のような感じになります。

npgsql SELECT 実行結果1

testtblのデータがDataGridViewに表示されています。

NpgsqlCommandでパラメータを指定する

SQLコマンド実行時に、条件の固定値などをパラメータとして動的に指定して実行することができます。
NpgsqlCommandクラスに渡すSQLコマンド文字列中で、パラメータとしたい部分を「:」で始まる文字列で指定します。(以下の例では「:param1」)
「NpgsqlParameter」にパラメータ文字列「param1」と型を指定し、「Value」に置き換える値を指定(以下の例では「80」)し、NpgsqlCommandのParametersに追加します。

  • VB.NET
  • C#
'SQLの実行
Dim sqlStr As String = "SELECT * FROM testtbl WHERE score >= :param1 ORDER BY score DESC"
Using cmd As New NpgsqlCommand(sqlStr, conn)
    'パラメータの設定(:param1の部分を80で置き換える)
    Dim prm As New NpgsqlParameter("param1", NpgsqlDbType.Integer)
    prm.Value = 80
    cmd.Parameters.Add(prm)
//SQLの実行
String sqlStr = "SELECT * FROM testtbl WHERE score >= :param1 ORDER BY score DESC";
using (NpgsqlCommand cmd = new NpgsqlCommand(sqlStr, conn))
{
    //パラメータの設定(:param1の部分を80で置き換える)
    NpgsqlParameter prm = new NpgsqlParameter("param1", NpgsqlTypes.NpgsqlDbType.Integer);
    prm.Value = 80;
    cmd.Parameters.Add(prm);

実行すると以下のような結果になります。

Npgsql SELECT 実行結果 パラメータ指定

scoreが80以上のデータが、scoreの降順でソートされています。

NpgsqlDataAdapterでデータを取得

ここまでの例ではDataTableへのデータ登録を1行ずつ行っていましたが、「NpgsqlDataAdapter」を使用してまとめて登録することが可能です。

  • VB.NET
  • C#
'DateTable初期化
Dim dt As New DataTable("testtbl")

          .
          .
          .

'SQLの実行
Dim sqlStr As String = "SELECT * FROM testtbl ORDER BY id"
Using cmd As New NpgsqlCommand(sqlStr, conn)

    '取得データをDataTableにセット
    Using da As New NpgsqlDataAdapter(cmd)
        da.Fill(dt)
    End Using

End Using

'DataGridViewにセット
Me.dgvData.DataSource = dt
//DataTable初期化
DataTable dt = new DataTable("testtbl");

          .
          .
          .

//SQLの実行
String sqlStr = "SELECT * FROM testtbl ORDER BY id";
using (NpgsqlCommand cmd = new NpgsqlCommand(sqlStr, conn))
{

    //取得データをDataAdapterにセット
    using (NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd))
    {
        da.Fill(dt);
    }

}

//DataGridViewにセット
dgvData.DataSource = dt;

NpgsqlDataAdapterのFill()でDataTableに取得データをセットしています。
実行すると以下のように取得データがセットされています。

Npgsql SELECT 実行結果 DataAdapter

今回のソースコード

最後に今回のサンプルのソースコード全文を貼っておきます。
それぞれフォームロード時にデータを取得してDataTableに登録し、それをDataGridViewにセットして表示しています。

SQLコマンドの実行結果を1行ずつ取得

  • VB.NET
  • C#
Imports Npgsql
Imports NpgsqlTypes

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' データ取得(1行ずつ全データ湯徳)

        '接続情報を設定
        Dim sb As New Npgsql.NpgsqlConnectionStringBuilder
        With sb
            .Host = "192.168.1.37"      'ホスト名、IPアドレス
            .Database = "testdb1"       'データベース名
            .Username = "testuser1"     '接続ユーザ名
            .Password = "testuser1"     'パスワード
            .Port = "5432"              '接続ポート番号
        End With

        'DateTable初期化
        Dim dt As New DataTable("testtbl")
        dt.Columns.Add("ID", GetType(String))
        dt.Columns.Add("名前", GetType(String))
        dt.Columns.Add("電話番号", GetType(String))
        dt.Columns.Add("メール", GetType(String))
        dt.Columns.Add("点数", GetType(Integer))

        'データベースへの接続
        Using conn As New NpgsqlConnection(sb.ConnectionString)
            Try
                conn.Open()

                'SQLの実行
                Dim sqlStr As String = "SELECT * FROM testtbl ORDER BY id"
                Using cmd As New NpgsqlCommand(sqlStr, conn)

                    'SQL実行結果の取得
                    Using reader As NpgsqlDataReader = cmd.ExecuteReader()
                        '1行ずつ取得
                        While (reader.Read())
                            '結果をDataTableにセット
                            Dim dr As DataRow = dt.NewRow()
                            dr.Item("ID") = reader.Item("id")
                            dr.Item("名前") = reader.Item("name")
                            dr.Item("電話番号") = reader.Item("tel")
                            dr.Item("メール") = reader.Item("email")
                            dr.Item("点数") = reader.Item("score")
                            dt.Rows.Add(dr)
                        End While
                    End Using

                End Using

                'DataGridViewにセット
                Me.dgvData.DataSource = dt

            Catch ex As Exception

                '例外メッセージ出力
                MsgBox(ex.Message, MsgBoxStyle.Critical)

            End Try
        End Using

    End Sub

End Class
using Npgsql;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace csnpgsql1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //1行ずつ全データ取得

            //接続情報を設定
            Npgsql.NpgsqlConnectionStringBuilder sb = new Npgsql.NpgsqlConnectionStringBuilder();
            sb.Host = "192.168.1.37";
            sb.Database = "testdb1";
            sb.Username = "testuser1";
            sb.Password = "testuser1";
            sb.Port = 5432;

            //DataTable初期化
            DataTable dt = new DataTable("testtbl");
            dt.Columns.Add("ID", typeof(String));
            dt.Columns.Add("名前", typeof(String));
            dt.Columns.Add("電話番号", typeof(String));
            dt.Columns.Add("メール", typeof(String));
            dt.Columns.Add("点数", typeof(int));

            //データベースへ接続
            using (Npgsql.NpgsqlConnection conn = new Npgsql.NpgsqlConnection(sb.ConnectionString))
            {
                conn.Open();

                //SQLの実行
                String sqlStr = "SELECT * FROM testtbl ORDER BY id";
                using (NpgsqlCommand cmd = new NpgsqlCommand(sqlStr, conn))
                {

                    //SQL結果取得
                    using (NpgsqlDataReader reader = cmd.ExecuteReader())
                    {
                        //1行ずつ取得
                        while (reader.Read())
                        {
                            DataRow dr = dt.NewRow();
                            dr["ID"] = reader["id"];
                            dr["名前"] = reader["name"];
                            dr["電話番号"] = reader["name"];
                            dr["メール"] = reader["email"];
                            dr["点数"] = reader["score"];
                            dt.Rows.Add(dr);
                        }
                    }

                }

                //DataGridViewにセット
                dgvData.DataSource = dt;

            }
        }
    }
}

SQLコマンドにパラメータを指定

  • VB.NET
  • C#
Imports Npgsql
Imports NpgsqlTypes

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'パラメータ指定

        '接続情報を設定
        Dim sb As New Npgsql.NpgsqlConnectionStringBuilder
        With sb
            .Host = "192.168.1.37"      'ホスト名、IPアドレス
            .Database = "testdb1"       'データベース名
            .Username = "testuser1"     '接続ユーザ名
            .Password = "testuser1"     'パスワード
            .Port = "5432"              '接続ポート番号
        End With

        'DateTable初期化
        Dim dt As New DataTable("testtbl")
        dt.Columns.Add("ID", GetType(String))
        dt.Columns.Add("名前", GetType(String))
        dt.Columns.Add("電話番号", GetType(String))
        dt.Columns.Add("メール", GetType(String))
        dt.Columns.Add("点数", GetType(Integer))

        'データベースへの接続
        Using conn As New NpgsqlConnection(sb.ConnectionString)
            Try
                conn.Open()

                'SQLの実行(パラメータ指定)
                Dim sqlStr As String = "SELECT * FROM testtbl WHERE score >= :param1 ORDER BY score DESC"
                Using cmd As New NpgsqlCommand(sqlStr, conn)
                    cmd.Parameters.Add(New NpgsqlParameter("param1", NpgsqlDbType.Integer))
                    cmd.Parameters("param1").Value = 80

                    'SQL実行結果の取得
                    Using reader As NpgsqlDataReader = cmd.ExecuteReader()
                        '1行ずつ取得
                        While (reader.Read())
                            '結果をDataTableにセット
                            Dim dr As DataRow = dt.NewRow()
                            dr.Item("ID") = reader.Item("id")
                            dr.Item("名前") = reader.Item("name")
                            dr.Item("電話番号") = reader.Item("tel")
                            dr.Item("メール") = reader.Item("email")
                            dr.Item("点数") = reader.Item("score")
                            dt.Rows.Add(dr)
                        End While
                    End Using

                End Using

                'DataGridViewにセット
                Me.dgvData.DataSource = dt

            Catch ex As Exception

                '例外メッセージ出力
                MsgBox(ex.Message, MsgBoxStyle.Critical)

            End Try

        End Using

    End Sub

End Class
using Npgsql;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace csnpgsql1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //パラメータ指定

            //接続情報の設定
            Npgsql.NpgsqlConnectionStringBuilder sb = new Npgsql.NpgsqlConnectionStringBuilder();
            sb.Host = "192.168.1.37";
            sb.Database = "testdb1";
            sb.Username = "testuser1";
            sb.Password = "testuser1";
            sb.Port = 5432;

            //DataTable初期化
            DataTable dt = new DataTable("testtbl");
            dt.Columns.Add("ID", typeof(String));
            dt.Columns.Add("名前", typeof(String));
            dt.Columns.Add("電話番号", typeof(String));
            dt.Columns.Add("メール", typeof(String));
            dt.Columns.Add("点数", typeof(int));

            //データベースへ接続
            using (Npgsql.NpgsqlConnection conn = new Npgsql.NpgsqlConnection(sb.ConnectionString))
            {
                conn.Open();

                //SQLの実行(パラメータ指定)
                String sqlStr = "SELECT * FROM testtbl WHERE score >= :param1 ORDER BY score DESC";
                using (NpgsqlCommand cmd = new NpgsqlCommand(sqlStr, conn))
                {
                    NpgsqlParameter prm = new NpgsqlParameter("param1", NpgsqlTypes.NpgsqlDbType.Integer);
                    prm.Value = 80;
                    cmd.Parameters.Add(prm);

                    //SQL結果取得
                    using (NpgsqlDataReader reader = cmd.ExecuteReader())
                    {
                        //1行ずつ取得
                        while (reader.Read())
                        {
                            DataRow dr = dt.NewRow();
                            dr["ID"] = reader["id"];
                            dr["名前"] = reader["name"];
                            dr["電話番号"] = reader["name"];
                            dr["メール"] = reader["email"];
                            dr["点数"] = reader["score"];
                            dt.Rows.Add(dr);
                        }

                    }
                }

                //DataGridViewにセット
                dgvData.DataSource = dt;

            }
        }
    }
}

DataAdapterによるDataTableへの登録

  • VB.NET
  • C#
Imports Npgsql
Imports NpgsqlTypes

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'データアダプタによるデータテーブルへの登録

        '接続情報を設定
        Dim sb As New Npgsql.NpgsqlConnectionStringBuilder
        With sb
            .Host = "192.168.1.37"      'ホスト名、IPアドレス
            .Database = "testdb1"       'データベース名
            .Username = "testuser1"     '接続ユーザ名
            .Password = "testuser1"     'パスワード
            .Port = "5432"              '接続ポート番号
        End With

        'DateTable初期化
        Dim dt As New DataTable("testtbl")

        'データベースへの接続
        Using conn As New NpgsqlConnection(sb.ConnectionString)
            Try
                conn.Open()

                'SQLの実行
                Dim sqlStr As String = "SELECT * FROM testtbl ORDER BY id"
                Using cmd As New NpgsqlCommand(sqlStr, conn)

                    'データ取得(データアダプタ)
                    Using da As New NpgsqlDataAdapter(cmd)
                        da.Fill(dt)
                    End Using

                End Using

                'DataGridViewにセット
                Me.dgvData.DataSource = dt

            Catch ex As Exception

                '例外メッセージ出力
                MsgBox(ex.Message, MsgBoxStyle.Critical)

            End Try

        End Using

    End Sub

End Class
using Npgsql;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace csnpgsql1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //アダプタによるデータテーブルへの登録

            //接続情報の設定
            Npgsql.NpgsqlConnectionStringBuilder sb = new Npgsql.NpgsqlConnectionStringBuilder();
            sb.Host = "192.168.1.37";
            sb.Database = "testdb1";
            sb.Username = "testuser1";
            sb.Password = "testuser1";
            sb.Port = 5432;

            //DataTable初期化
            DataTable dt = new DataTable("testtbl");

            //データベースへ接続
            using (Npgsql.NpgsqlConnection conn = new Npgsql.NpgsqlConnection(sb.ConnectionString))
            {
                conn.Open();

                //SQLの実行
                String sqlStr = "SELECT * FROM testtbl ORDER BY id";
                using (NpgsqlCommand cmd = new NpgsqlCommand(sqlStr, conn))
                {

                    //取得データをDataTableにセット
                    using (NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd))
                    {
                        da.Fill(dt);
                    }

                }

                //DataGridViewにセット
                dgvData.DataSource = dt;

            }
        }
    }
}

以上です。

タイトルとURLをコピーしました