首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以作为参数直接传递回游标,以便在Npgsql上获取?

是否可以作为参数直接传递回游标,以便在Npgsql上获取?
EN

Stack Overflow用户
提问于 2019-05-13 12:45:05
回答 1查看 577关注 0票数 0

当对FETCH使用Npgsql库时,我找不到任何方法将游标ref作为参数传递给PostgreSQL命令。这个是可能的吗?

代码语言:javascript
复制
using (DbConnection connection = new NpgsqlConnection(connectionString))
{
    connection.Open();
    using (DbTransaction transaction = connection.BeginTransaction())
    {
        var outCursor = new NpgsqlParameter("cursor", NpgsqlTypes.NpgsqlDbType.Refcursor);
        outCursor.Direction = ParameterDirection.Output;

        // get a refcursor from somewhere
        using (DbCommand commandGet = connection.CreateCommand())
        {
            commandGet.CommandText = "get_cursor";
            commandGet.CommandType = CommandType.StoredProcedure;
            commandGet.Parameters.Add(outCursor);
            commandGet.Connection = connection;
            commandGet.ExecuteNonQuery();
        }

        // try to use it
        using (DbCommand commandFetch = connection.CreateCommand())
        {
            var inCursor = new NpgsqlParameter("cursor", NpgsqlTypes.NpgsqlDbType.Refcursor);
            inCursor.Direction = ParameterDirection.Input;
            inCursor.Value = outCursor.Value;

            // This commented out line using string interpolation works fine.
            // Can it be done with a parameter, as I'm trying to do below?
            //commandFetch.CommandText = $"FETCH 100 FROM \"{outCursor.Value}\"";

            // The same inCursor pattern used here works fine when the cursor is being passed
            // on to a function, but does not work for FETCH
            commandFetch.CommandText = $"FETCH 100 FROM :cursor";
            commandFetch.Parameters.Add(inCursor);

            commandFetch.Connection = connection;

            // This line fails for param-based version; 
            // works fine with string-interpolation version
            using (var reader = commandFetch.ExecuteReader())
            {
                while (reader.Read())
                {
                    int a = (int)reader[0];
                }
            }
        }

        // close it
        using (DbCommand commandClose = connection.CreateCommand())
        {
            // I would like to be able to pass the cursor as a true parameter here, too
            commandClose.CommandText = $"CLOSE \"{outCursor.Value}\"";
            commandClose.Connection = connection;
            var reader = commandClose.ExecuteNonQuery();
        }
    }
}

注意注释的行:我可以让代码正常工作,我只想找到一种方法使其工作,将游标ref作为参数传递回。

我得到的例外是Npgsql.PostgresException : 42601: syntax error at or near "$1"

传递一个普通字符串值参数(该参数看起来可能工作.)也会失败,但也有相同的例外。

如果要将输入游标传递给函数,则从输出游标创建输入游标的上述模式工作良好。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-13 17:42:15

This Stack Overflow answer加上它的后续注释基本上回答说,由于底层数据库中的一种轻量化,不可能完成我想要做的事情(至少在创建和执行动态SQL之前是不可能的)。

不能在FETCH语句中使用变量。使用动态SQL: EXECUTE格式(‘从%i取回所有“,foo);

因此,这不是Npgsql的限制,另一个答案中提出的解决方案也可以应用于Npgsql。或者,您只需将字符串插入到SQL中即可,这在某种程度上是“丑陋的”(至少对我来说是如此),实际上是非常安全的。

(在这种情况下--但直接将值插入SQL通常是个坏主意,至少无需三思为什么,甚至在任何给定的有限使用中-在所有可能的情况下,它都是安全的,不受注入攻击。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56112658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档