使用 NPGSQL 执行原始 SQL 时如何得到 "no rows" 错误?

How to get "no rows" error when execute raw SQL with NPGSQL?

我是 C# 的新手,所以如果这是一个显而易见的问题但我似乎找不到答案,我深表歉意。我正在编写一个客户端应用程序,它采用原始 SQL 命令并将其直接传递给数据库。我不知道它会是 selectupdateinsert 还是 delete。如果是select,我想把结果变成DataTable。如果是别的,我想知道是执行成功了还是执行出错了(比如:没有行受到影响)。

我目前正在执行以下代码,然后才发现 return updatedelete 的任何错误都不会影响任何行。我格式化了代码,但试图留下足够的空间来理解我想要做什么。由于这是我在这里的第一个问题,如果您有任何关于如何更好地将我的问题背景化的提示,请分享。

class Client
{
    static void Main(string[] args)
    {
        Config.LoadConfig();
        Db.Init();

        var testQuery1 = "select * from test where 1=1";
        var testQuery2 = "update test set value='value3' where name = 'name3'";
        var testQuery3 = "insert into test (id, name, value, date) values (4,'name4','value4',current_timestamp)";

        Db.Query(testQuery1);
        Db.PrintResults();

        Db.Query(testQuery2);
        Db.PrintResults();

        Db.Query(testQuery3);
        Db.PrintResults();
    }
}

/// <summary>
/// Universal database class.
/// </summary>
public static partial class Db
{
    private static IUniversalDatabase _dbUniConn;

    /* Database Results */
    public static string ErrorCode { get; private set; }
    public static string ErrorMessage { get; private set; }
    public static int RowCount { get; private set; }
    public static double ExecutionSeconds { get; private set; }
    public static DataTable Data { get; private set; } = new DataTable();

    public static void Init(string connString, Type dbType)
    {
        try
        {
            _connString = connString;
            _connType = dbType;

            switch (_connType)
            {
                case Db.Type.PostgreSQL:
                    _dbUniConn = new PostgresDatabase(_connString);
                    break;
                ...
            }
        }
    }

    public static void Open()
    { ...  _dbUniConn.Open(); ...  }

    public static void Close()
    { ...  _dbUniConn.Close(); ...  }

    public static void Query(string cmdString)
    {
        var start = DateTime.Now;

        Open();

        /* Reset Data */
        Data.Reset();
        RowCount = 0;
        ErrorMessage = "";
        ErrorCode = "";

        /* Execute Query */
        _dbUniConn.Query(cmdString);

        /* Execution Time */
        ExecutionSeconds = (DateTime.Now - start).TotalSeconds;
        Debug.Write("Database:    Execution Time: " + ExecutionSeconds.ToString() + " seconds", Debug.TraceLevel.Info);

        /* RowCount and Error Message */
        RowCount = Data.Rows.Count;
        Debug.Write("Database:    Returning " + RowCount.ToString() + " rows", Debug.TraceLevel.Info);
        Debug.Write("Database:    Error (" + ErrorCode + "): " + ErrorMessage, Debug.TraceLevel.Info);

        Close();
    }

    public class PostgresDatabase : IUniversalDatabase
    {
        private NpgsqlConnection _dbConn;

        public PostgresDatabase(string connString)
        { _dbConn = new NpgsqlConnection(connString); }

        public void Open()
        { _dbConn.Open(); }

        public void Close()
        { _dbConn.Close(); }

        public void Dispose()
        { _dbConn.Dispose(); }

        public void Query(string cmdString)
        {
            NpgsqlCommand cmd = new NpgsqlCommand(cmdString, _dbConn);
            NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd);
            cmd.CommandType = System.Data.CommandType.Text;

            try
            {
                da.Fill(Data);
            }
            catch (Exception e)
            {
                MatchCollection configVar = Regex.Matches(e.Message.ToString(), @"^(?<code>.*?): (?<msg>.*?)$");
                foreach (Match match in configVar)
                {
                    ErrorCode = match.Groups["code"].Value.ToString();
                    ErrorMessage = match.Groups["msg"].Value.ToString();
                }
            }
            da.Dispose();
            cmd.Dispose();
        }
    }
}

我通过在查询以 select:

以外的任何内容开始时将 RETURNING 1 添加到我的查询中来解决此问题
        public void Query()
        {
            Match m = Regex.Match(QueryInput.queryString, @"^\s*(?i:select).*$");
            if (!m.Success)
            {
                QueryInput.queryString += " RETURNING 1";
            }

            NpgsqlCommand cmd = new NpgsqlCommand(QueryInput.queryString, _dbConn);
            NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd);
            cmd.CommandType = System.Data.CommandType.Text;

            try
            {
                da.Fill(Data);
            }
            catch (Exception e)
            {
                m = Regex.Match(e.Message.ToString(), @"^(?<code>.*?): (?<msg>.*?)$");
                if (m.Success)
                {
                    ErrorCode = m.Groups["code"].Value.ToString();
                    ErrorMessage = m.Groups["msg"].Value.ToString();
                }
                else
                    throw e;
            }
            da.Dispose();
            cmd.Dispose();
        }
    }

我用以下方法对此进行了测试:

            Db.Query("update test set value = 'value1' where name in (\nselect name from test where name = 'name1')", Db.Type.PostgreSQL);
            Db.PrintResults();

            Db.Query("\nSELECT * from test limit 10", Db.Type.PostgreSQL);
            Db.PrintResults();

            Db.Query("update test set value='new value' where name='name1'", Db.Type.PostgreSQL);
            Db.PrintResults();

            Db.Query("insert into test (id,name,value,date) values (3,'name3',value3,current_timestamp)", Db.Type.PostgreSQL);
            Db.PrintResults();

            Db.Query("delete from test where id = 3", Db.Type.PostgreSQL);
            Db.PrintResults();

这返回了以下结果:

13:43:57:014 - Info  - Database: Received [PostgreSQL] command (update test set value = 'value1' where name in (
select name from test where name = 'name1'))
13:43:57:015 - Debug - Database: Connection is now opened.
13:43:57:070 - Info  - Database:    Execution Time: 0.055539 seconds
13:43:57:071 - Info  - Database:    Returning 1 rows
13:43:57:071 - Info  - Database:    Error (0): Success.
13:43:57:071 - Debug - Database: Connection is now closed.
13:43:57:072 - Debug - Database: Result      ?column?
13:43:57:072 - Debug - Database: Result   1: 1

13:43:57:072 - Info  - Database: Received [PostgreSQL] command (
SELECT * from test limit 10)
13:43:57:072 - Debug - Database: Connection is now opened.
13:43:57:088 - Info  - Database:    Execution Time: 0.0160114 seconds
13:43:57:088 - Info  - Database:    Returning 2 rows
13:43:57:088 - Info  - Database:    Error (0): Success.
13:43:57:089 - Debug - Database: Connection is now closed.
13:43:57:089 - Debug - Database: Result      id        name      value     date
13:43:57:089 - Debug - Database: Result   1: 1         name1     value1    6/14/2017 8:37:48 PM
13:43:57:089 - Debug - Database: Result   2: 2         name2     value2    6/14/2017 8:37:48 PM

13:43:57:089 - Info  - Database: Received [PostgreSQL] command (update test set value='new value' where name='name1')
13:43:57:089 - Debug - Database: Connection is now opened.
13:43:57:090 - Info  - Database:    Execution Time: 0.0010007 seconds
13:43:57:090 - Info  - Database:    Returning 1 rows
13:43:57:091 - Info  - Database:    Error (0): Success.
13:43:57:092 - Debug - Database: Connection is now closed.
13:43:57:093 - Debug - Database: Result      ?column?
13:43:57:093 - Debug - Database: Result   1: 1

13:43:57:094 - Info  - Database: Received [PostgreSQL] command (insert into test (id,name,value,date) values (3,'name3',value3,current_timestamp))
13:43:57:096 - Debug - Database: Connection is now opened.
13:43:57:186 - Info  - Database:    Execution Time: 0.0920653 seconds
13:43:57:187 - Info  - Database:    Returning 0 rows
13:43:57:191 - Info  - Database:    Error (42703): column "value3" does not exist
13:43:57:192 - Debug - Database: Connection is now closed.
13:43:57:199 - Debug - Database: Result

13:43:57:200 - Info  - Database: Received [PostgreSQL] command (delete from test where id = 3)
13:43:57:201 - Debug - Database: Connection is now opened.
13:43:57:204 - Info  - Database:    Execution Time: 0.0040029 seconds
13:43:57:204 - Info  - Database:    Returning 0 rows
13:43:57:205 - Info  - Database:    Error (-1403): No rows found.
13:43:57:205 - Debug - Database: Connection is now closed.
13:43:57:206 - Debug - Database: Result      ?column?