在 PostgreSQL 中将数据表作为参数传递

Aja*_*tni 7 postgresql c#

我在 asp.net C# 中有一个数据表。我想将该数据表作为表参数传递给 PostgreSQL 函数。这怎么可能?

下面的示例是相同的,但它在 SQL Server 中。我需要同样的东西,但问题是我有 PostgreSQL 作为后端,而不是 SQL Server。

介绍

SQL Server 存储过程支持 System.Data.DataTable 作为参数。我们可以使用 ADO.Net 以与使用 System.Data.SqlParameter 类相同的方式将 DataTable 传递给存储过程,但需要对数据类型进行一些更改。通常我们为varchar、nvarchar、int 等普通参数提供SqlParameter 的DbType,如下面的代码所示。

SqlParameter sqlParam= new SqlParameter();  
sqlParam.ParameterName = "@StudentName";  
sqlParam.DbType = DbType.String;  
sqlParam.Value = StudentName;  
Run Code Online (Sandbox Code Playgroud)

但是在 Table 参数的情况下,我们不需要提供 DbType作为参数数据类型。我们需要提供SqlType而不是 DbType。

例子

SqlParameter Parameter = new SqlParameter;  
Parameter.ParameterName = "@PhoneBook";  
Parameter.SqlDbType = SqlDbType.Structured;  
Parameter.Value = PhoneTable;  
Run Code Online (Sandbox Code Playgroud)

下面的示例接收电话簿列表并使用 ADO.Net 将它们存储在数据库中。该示例从列表中检索电话簿详细信息并将它们存储到 DataTable 中,并将该表作为参数传递给名为 NewPhoneBook 的存储过程。

//Phone book list    
List<PhoneBook> PhoneBooks    
 //CReating Table    
 DataTable PhoneTable = new DataTable();    

 // Adding Columns    
 DataColumn COLUMN=new DataColumn();    
 COLUMN.ColumnName="ID";    
 COLUMN.DataType= typeof(int);    
 PhoneTable.Columns.Add(COLUMN);    

 COLUMN = new DataColumn();    
 COLUMN.ColumnName = "ContactNumber";    
 COLUMN.DataType = typeof(string);    
 PhoneTable.Columns.Add(COLUMN);    

 COLUMN = new DataColumn();    
 COLUMN.ColumnName = "ContactName";    
 COLUMN.DataType = typeof(string);    
 PhoneTable.Columns.Add(COLUMN);    

 // INSERTING DATA    
 foreach (UserPhoneBook UPB in PhoneBooks)    
 {    
    DataRow DR = PhoneTable.NewRow();    
    DR[0] = UPB.UserName;    
    DR[1] = UPB.ContactNumber;    
    DR[2] = UPB.ContactName;    
    PhoneTable.Rows.Add(DR);    
 }    
 //Parameter declaration    
 SqlParameter[] Parameter = new SqlParameter[2];    
 Parameter[0].ParameterName = "@PhoneBook";    
 Parameter[0].SqlDbType = SqlDbType.Structured;    
 Parameter[0].Value = PhoneTable;    

 Parameter[1].ParameterName = "@Return_Value";    
 Parameter[1].Direction = ParameterDirection.ReturnValue;    
 //Executing Procedure  
 SqlHelper.ExecuteNonQuery(this.ConnectionString, CommandType.StoredProcedure, "[NewPhoneBook]", Parameter);
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到代码参考

Eva*_*oll 5

我永远不会使用这些对象。它们似乎没有那么有用。也就是说,PostgreSQL 确实有一种方法可以通过jsonb. 如果您希望获得Passing a Table-Valued Parameter to a Stored Procedure 中描述的功能,这可能是您的理想解决方案。您所要做的就是将 DataTable 映射到 JSON,然后将 JSON 传递给函数。

要将数据表转换为 JSON,您可以使用JSON.net。另请参阅这些堆栈溢出答案。

如果数据表太大而无法序列化为 JSON,您可能必须围绕导出 DataRow 对象的内容创建一个外部数据包装器,这将使您沿着“使用 DataReader 流式处理行”中提到的路径开始。虽然如果您不需要服务器/客户端模型,您始终可以将 DataTable 转储到 CSV 并使用外部数据包装器读取它:沿着该路线检查file-fdw

我实际上试过这个。我遇到了很多问题。

  1. 弄清楚如何使用 nuGet 安装包并不容易,
  2. 已经安装了 nuGet,尽管它是 nuGet 上的 #1 包,但它还不能与 .NET Core 2.x 一起使用
  3. 安装nuGet测试版,我让它工作了。

使用 .NET Core 2.x 将数据表转换为 JSON,

using System;
using System.Data;
using Newtonsoft.Json;

class Program
{
  static void Main()
  {
    // Get the DataTable.
    DataTable table = GetTable();
    // ... Use the DataTable here with SQL.
    string json = JsonConvert.SerializeObject(table, Formatting.Indented);
    Console.WriteLine(json);

  }

  static DataTable GetTable()
  {
    // Here we create a DataTable with four columns.
    DataTable table = new DataTable();
    table.Columns.Add("Dosage", typeof(int));
    table.Columns.Add("Drug", typeof(string));
    table.Columns.Add("Patient", typeof(string));
    table.Columns.Add("Date", typeof(DateTime));

    // Here we add five DataRows.
    table.Rows.Add(25, "Indocin", "David", DateTime.Now);
    table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
    table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
    table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
    table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);

    return table;
  }
}
Run Code Online (Sandbox Code Playgroud)

您仍然必须连接到数据库并将 json 放入INSERT语句中,但这应该很容易完成。

cmd.CommandText = "SELECT * FROM myfunc(@json)";
cmd.Parameters.AddWithValue("json", json);
Run Code Online (Sandbox Code Playgroud)

myfunc(jsonb)在服务器上定义,你应该很好:你已经将 a 传递给DataTable了 PostgreSQL。