无法将 SQL 查询响应映射到 C# 变量
Unable to map SQL Query Response to C# variables
我有这个 SQL 查询脚本,我正试图通过 ADO.Net 代码调用它。
DECLARE
@Error NVARCHAR(MAX)
DECLARE
@Errors TABLE
(
[Column_Name] VARCHAR(MAX),
[Message] VARCHAR(MAX)
)
IF NOT EXISTS(...)
BEGIN
INSERT INTO @Errors
SELECT
'Col1',
'value does not exist.'
END
IF NOT EXISTS(...)
BEGIN
INSERT INTO @Errors
SELECT
'Col2',
'value does not exist.'
END
IF EXISTS (SELECT * FROM @Errors)
BEGIN
SET @Error = (
SELECT
[Column_Name],
[Message]
FROM
@Errors
FOR JSON PATH, INCLUDE_NULL_VALUES
);
SELECT @Error AS 'Error_Message'
END
ELSE
BEGIN
SELECT TOP(1) Id
FROM dbo.table
END
这是 C# 代码
using (var conn = await _connectionFactory.OpenConnectionAsync(database: "dbName", readOnly: true))
{
using (var cmd = conn.CreateCommandFromSqlFile(path, "test.sql"))
{
string errors = string.Empty;
Guid id;
using (DataReader reader = await cmd.ExecuteReaderAsync(ct))
{
if (reader.HasRows)
{
while (await reader.ReadAsync(ct))
{
errors = reader.GetString("Error_Message");
id = reader.GetGuid("Id");
}
}
}
}
}
SQL 脚本总是 returns、Error_Message
或 Id
,具体取决于条件。如果 @Errors
table 被填充,它 returns Error_Message
如果没有错误那么它 returns Id
.
我试图在 C# 代码中获取这些值,但它在 while
块中抛出异常,因为其中一个值 Error_Message
或 Id
不会出席。
我需要帮助才能将这些值优雅地添加到我的 C# 代码中。有办法吗?
您可以使用SqlDataReader
的GetName
功能
using (SqlDataReader reader = await cmd.ExecuteReaderAsync(ct))
{
if (reader.HasRows)
{
while (await reader.ReadAsync(ct))
{
var colName = reader.GetName(0);
if (colName.Equals("Error_Message")
errors = reader.GetString("Error_Message");
else
id = reader.GetGuid("Id");
}
}
}
我认为没有一种“优雅”的方式可以按照您构建它的方式来做,恕我直言
- 您可以使用 c# try catch 来捕获不存在错误时发生的异常,但异常处理很慢,不应用作正常的控制流程
- 您可以更改您的查询,使它们 return 具有相同的列名,这样就不会再有任何例外,并且 id 表示为一个字符串,并且您可以使用另一列来指导您字符串是 GUId 还是错误,以便您可以适当地解析或报告它,或者您尝试解析它并查看它是否有效
- 您可以更改查询,使它们始终有两列 - 一个字符串和一个 GUId,其中一列始终为 null,并使用 null 来确定您拥有哪种类型的东西
- 您总是可以 select 您的错误和 ID,并利用 sql 服务器允许您打开多个结果集的事实
但实际上我认为我会停止尝试将 return SQL 错误作为结果集而只是 throw them as exceptions,并在 c# 中捕获它们。采用以空白开头的字符串的模式,检查 col1,如果不存在,则将“col1 不存在”附加到字符串,检查 col2 并可能附加“col2 不存在”.. 然后如果字符串不为空 THROW it,否则 return 您的结果集。 C# 会遇到异常并显示有用的错误消息(如果您想以不同的方式处理它,而不是仅仅向用户报告,您可以提供可变代码)
我有这个 SQL 查询脚本,我正试图通过 ADO.Net 代码调用它。
DECLARE
@Error NVARCHAR(MAX)
DECLARE
@Errors TABLE
(
[Column_Name] VARCHAR(MAX),
[Message] VARCHAR(MAX)
)
IF NOT EXISTS(...)
BEGIN
INSERT INTO @Errors
SELECT
'Col1',
'value does not exist.'
END
IF NOT EXISTS(...)
BEGIN
INSERT INTO @Errors
SELECT
'Col2',
'value does not exist.'
END
IF EXISTS (SELECT * FROM @Errors)
BEGIN
SET @Error = (
SELECT
[Column_Name],
[Message]
FROM
@Errors
FOR JSON PATH, INCLUDE_NULL_VALUES
);
SELECT @Error AS 'Error_Message'
END
ELSE
BEGIN
SELECT TOP(1) Id
FROM dbo.table
END
这是 C# 代码
using (var conn = await _connectionFactory.OpenConnectionAsync(database: "dbName", readOnly: true))
{
using (var cmd = conn.CreateCommandFromSqlFile(path, "test.sql"))
{
string errors = string.Empty;
Guid id;
using (DataReader reader = await cmd.ExecuteReaderAsync(ct))
{
if (reader.HasRows)
{
while (await reader.ReadAsync(ct))
{
errors = reader.GetString("Error_Message");
id = reader.GetGuid("Id");
}
}
}
}
}
SQL 脚本总是 returns、Error_Message
或 Id
,具体取决于条件。如果 @Errors
table 被填充,它 returns Error_Message
如果没有错误那么它 returns Id
.
我试图在 C# 代码中获取这些值,但它在 while
块中抛出异常,因为其中一个值 Error_Message
或 Id
不会出席。
我需要帮助才能将这些值优雅地添加到我的 C# 代码中。有办法吗?
您可以使用SqlDataReader
GetName
功能
using (SqlDataReader reader = await cmd.ExecuteReaderAsync(ct))
{
if (reader.HasRows)
{
while (await reader.ReadAsync(ct))
{
var colName = reader.GetName(0);
if (colName.Equals("Error_Message")
errors = reader.GetString("Error_Message");
else
id = reader.GetGuid("Id");
}
}
}
我认为没有一种“优雅”的方式可以按照您构建它的方式来做,恕我直言
- 您可以使用 c# try catch 来捕获不存在错误时发生的异常,但异常处理很慢,不应用作正常的控制流程
- 您可以更改您的查询,使它们 return 具有相同的列名,这样就不会再有任何例外,并且 id 表示为一个字符串,并且您可以使用另一列来指导您字符串是 GUId 还是错误,以便您可以适当地解析或报告它,或者您尝试解析它并查看它是否有效
- 您可以更改查询,使它们始终有两列 - 一个字符串和一个 GUId,其中一列始终为 null,并使用 null 来确定您拥有哪种类型的东西
- 您总是可以 select 您的错误和 ID,并利用 sql 服务器允许您打开多个结果集的事实
但实际上我认为我会停止尝试将 return SQL 错误作为结果集而只是 throw them as exceptions,并在 c# 中捕获它们。采用以空白开头的字符串的模式,检查 col1,如果不存在,则将“col1 不存在”附加到字符串,检查 col2 并可能附加“col2 不存在”.. 然后如果字符串不为空 THROW it,否则 return 您的结果集。 C# 会遇到异常并显示有用的错误消息(如果您想以不同的方式处理它,而不是仅仅向用户报告,您可以提供可变代码)