如何将参数传递给 postgre 函数并使用 ExecuteReader 获取数据?
How to pass the parameter to a postgre function and get data using ExecuteReader?
我正在尝试使用 C# 中的 ExecuteReader 从 table 中检索所有列 application.Db 是 postgre.To 测试 我按照教程创建了一个控制台应用程序,其中显示了如何查询使用函数但不使用传递 parameters.The 控制台应用程序函数进行测试
static void Main(string[] args)
{
// Connect to a PostgreSQL database
NpgsqlConnection conn = new NpgsqlConnection("Server=localhost;User Id=postgres; " +
"Password=pes;Database=pmc;");
conn.Open();
// Define a query
NpgsqlCommand command = new NpgsqlCommand("SELECT * from audit.exception_gl_accounts()", conn);
// Execute the query and obtain a result set
NpgsqlDataReader dr = command.ExecuteReader();
// Output rows
while (dr.Read())
Console.Write("{0}\t{1} \n", dr[0], dr[1]);
conn.Close();
}
}
在 NpgsqlCommand 中,我将不带参数的查询发送给函数 audit.exception_gl_accounts 并且它起作用了 well.Now 我如何将参数传递给这样的函数
"SELECT * FROM sms.get_accounts_info(@AccountNumber);
我正在尝试使用此函数检索所有 5 列并获取这些对象
public static string GetAccountInfo(string accountNumber)
{
NpgsqlConnection conn = new NpgsqlConnection("Server=localhost;User
Id=postgres; " + "Password=pes;Database=pmc;");
conn.Open();
NpgsqlCommand command = new NpgsqlCommand("SELECT * FROM
sms.get_accounts_info(@AccountNumber); ", conn);
command.Parameters.AddWithValue("@AccountNumber", accountNumber);
NpgsqlDataReader dr = command.ExecuteReader();
while (dr.Read())
Console.Write("{0}\t{1} \n", dr[0], dr[1]);
return dr.ToString();
}
使用第二个示例代码会出现此错误:
{
"accountNumber": "Npgsql.ForwardsOnlyDataReader",
"balance": null,
"interestRate": 0,
"accountName": null,
"accountType": null
}
感谢任何帮助。
详细信息已更新
控制器
[HttpPost]
[ActionName("info")]
public IHttpActionResult GetAccountInfo([FromBody]AccountInfo
accountinfo)
{
accountinfo.accountNumber = BusinessLayer.Api.AccountHolderApi.GetAccountInfo
(accountinfo.accountNumber);
return Ok(accountinfo);
}
账户信息Class
public class AccountInfo
{
public string accountNumber { get; set; }
public string balance { get; set; }
public int interestRate { get; set; }
public string accountName { get; set; }
public string accountType { get; set; }
}
URI
获取帐户信息
CREATE OR REPLACE FUNCTION sms.get_accounts_info(IN account_number_ character varying)
RETURNS TABLE(account_number character varying, account_name text, product character varying, interest_rate numeric, balance money) AS
$BODY$
BEGIN
RETURN QUERY(
SELECT a.account_number,
c.customer_name,
p.deposit_product_name,
a.interest_rate::numeric, deposit.get_balance(account_number_)
FROM deposit.account_holders a
JOIN core.customers_view c ON a.customer_id = c.customer_id
JOIN core.deposit_products p ON a.deposit_product_id = p.deposit_product_id
WHERE a.account_number =
);
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION sms.get_accounts_info(character varying)
OWNER TO postgres;
如果没有 entity framework,您需要编写代码,将数据读取器中的值读取到您的 AccountInfo
class:
的实例中
public static AccountInfo GetAccountInfo(string accountNumber)
{
AccountInfo result = null;
using(var conn = new NpgsqlConnection("..."))
{
conn.Open();
using(var command = new NpgsqlCommand("SELECT * FROM sms.get_accounts_info(@AccountNumber); ", conn))
{
command.Parameters.AddWithValue("@AccountNumber", accountNumber);
using(var dr = command.ExecuteReader())
{
if(dr.HasRows && dr.Read())
{
result = new AccountInfo {
accountNumber = dr["accountNumber"].ToString(),
balance = dr["balance"].ToString(),
interestRate = Convert.ToInt32(dr["interestRate"]),
accountName = dr["accountName"].ToString()
};
}
}
}
}
return result;
}
请注意,函数的 return 类型已更改为 AccountInfo
,之前为字符串。此外,它仅限于读取一条记录,如果对 sms.get_accounts_info
的一次调用可以 return 多条记录,那就是另一回事了。我只是假设 account_number
是 account_holders
table.
中的主键
有些细节需要注意,例如balance
是数据库中的钱,而class中是字符串。另外我不知道product
(数据库)和accountType
(class)是否以及如何对应,所以我省略了它。
数据库连接、命令和数据读取器是 IDisposable
,应包装在 using
个块中。
我正在尝试使用 C# 中的 ExecuteReader 从 table 中检索所有列 application.Db 是 postgre.To 测试 我按照教程创建了一个控制台应用程序,其中显示了如何查询使用函数但不使用传递 parameters.The 控制台应用程序函数进行测试
static void Main(string[] args)
{
// Connect to a PostgreSQL database
NpgsqlConnection conn = new NpgsqlConnection("Server=localhost;User Id=postgres; " +
"Password=pes;Database=pmc;");
conn.Open();
// Define a query
NpgsqlCommand command = new NpgsqlCommand("SELECT * from audit.exception_gl_accounts()", conn);
// Execute the query and obtain a result set
NpgsqlDataReader dr = command.ExecuteReader();
// Output rows
while (dr.Read())
Console.Write("{0}\t{1} \n", dr[0], dr[1]);
conn.Close();
}
}
在 NpgsqlCommand 中,我将不带参数的查询发送给函数 audit.exception_gl_accounts 并且它起作用了 well.Now 我如何将参数传递给这样的函数
"SELECT * FROM sms.get_accounts_info(@AccountNumber);
我正在尝试使用此函数检索所有 5 列并获取这些对象
public static string GetAccountInfo(string accountNumber)
{
NpgsqlConnection conn = new NpgsqlConnection("Server=localhost;User
Id=postgres; " + "Password=pes;Database=pmc;");
conn.Open();
NpgsqlCommand command = new NpgsqlCommand("SELECT * FROM
sms.get_accounts_info(@AccountNumber); ", conn);
command.Parameters.AddWithValue("@AccountNumber", accountNumber);
NpgsqlDataReader dr = command.ExecuteReader();
while (dr.Read())
Console.Write("{0}\t{1} \n", dr[0], dr[1]);
return dr.ToString();
}
使用第二个示例代码会出现此错误:
{ "accountNumber": "Npgsql.ForwardsOnlyDataReader", "balance": null, "interestRate": 0, "accountName": null, "accountType": null }
感谢任何帮助。
详细信息已更新
控制器
[HttpPost]
[ActionName("info")]
public IHttpActionResult GetAccountInfo([FromBody]AccountInfo
accountinfo)
{
accountinfo.accountNumber = BusinessLayer.Api.AccountHolderApi.GetAccountInfo
(accountinfo.accountNumber);
return Ok(accountinfo);
}
账户信息Class
public class AccountInfo
{
public string accountNumber { get; set; }
public string balance { get; set; }
public int interestRate { get; set; }
public string accountName { get; set; }
public string accountType { get; set; }
}
URI
获取帐户信息
CREATE OR REPLACE FUNCTION sms.get_accounts_info(IN account_number_ character varying)
RETURNS TABLE(account_number character varying, account_name text, product character varying, interest_rate numeric, balance money) AS
$BODY$
BEGIN
RETURN QUERY(
SELECT a.account_number,
c.customer_name,
p.deposit_product_name,
a.interest_rate::numeric, deposit.get_balance(account_number_)
FROM deposit.account_holders a
JOIN core.customers_view c ON a.customer_id = c.customer_id
JOIN core.deposit_products p ON a.deposit_product_id = p.deposit_product_id
WHERE a.account_number =
);
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION sms.get_accounts_info(character varying)
OWNER TO postgres;
如果没有 entity framework,您需要编写代码,将数据读取器中的值读取到您的 AccountInfo
class:
public static AccountInfo GetAccountInfo(string accountNumber)
{
AccountInfo result = null;
using(var conn = new NpgsqlConnection("..."))
{
conn.Open();
using(var command = new NpgsqlCommand("SELECT * FROM sms.get_accounts_info(@AccountNumber); ", conn))
{
command.Parameters.AddWithValue("@AccountNumber", accountNumber);
using(var dr = command.ExecuteReader())
{
if(dr.HasRows && dr.Read())
{
result = new AccountInfo {
accountNumber = dr["accountNumber"].ToString(),
balance = dr["balance"].ToString(),
interestRate = Convert.ToInt32(dr["interestRate"]),
accountName = dr["accountName"].ToString()
};
}
}
}
}
return result;
}
请注意,函数的 return 类型已更改为 AccountInfo
,之前为字符串。此外,它仅限于读取一条记录,如果对 sms.get_accounts_info
的一次调用可以 return 多条记录,那就是另一回事了。我只是假设 account_number
是 account_holders
table.
有些细节需要注意,例如balance
是数据库中的钱,而class中是字符串。另外我不知道product
(数据库)和accountType
(class)是否以及如何对应,所以我省略了它。
数据库连接、命令和数据读取器是 IDisposable
,应包装在 using
个块中。