微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 C# 中如何使用 StackExchange.Redis Execute 方法为 sql 语句提供参数,使用 Redis 和 Redisql 模块

如何解决在 C# 中如何使用 StackExchange.Redis Execute 方法为 sql 语句提供参数,使用 Redis 和 Redisql 模块

关于 Redisql 模块与 C# 的使用的信息非常有限。

我使用 StackExchange.Redis nuget 包 v2.2.4 来连接安装了 Redisql 模块的 Redis v5.0.7。我正在开发 .NET 5 C# 应用程序,该应用程序连接并创建具有预定义值的数据库和表。

以下是运行正常且符合预期的代码块。

    ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect("127.0.0.1:6380");
    IDatabase conn = muxer.GetDatabase();

    conn.Execute("DEL","DB");

    conn.Execute("REDIsql.CREATE_DB","DB");
    conn.Execute("REDIsql.EXEC","DB","CREATE TABLE TABLE1(A INT,B TEXT);");
    conn.Execute("REDIsql.EXEC","INSERT INTO TABLE1 VALUES(1,'Value1');");
    conn.Execute("REDIsql.EXEC","INSERT INTO TABLE1 VALUES(2,'Value2');");
    var res = conn.Execute("REDIsql.EXEC","SELECT * FROM TABLE1");

但我想要做的是执行带有 db 参数的插入语句,而不是直接在 sql 语句中提供值。由于实际上没有任何示例或文档,我无法找到方法来做到这一点。

我试图重写插入语句如下,但它给出了错误

conn.Execute("REDIsql.EXEC","INSERT INTO TABLE1 VALUES(?1,?2);",1,"Value1");

StackExchange.Redis.RedisServerException:“参数数量错误, 它接受 3,你提供 5" StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](消息 消息、ResultProcessor1 processor,ServerEndPoint server) in /_/src/StackExchange.Redis/ConnectionMultiplexer.cs:line 2817\n at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message,ResultProcessor1 个处理器、ServerEndPoint 服务器)在 //src/StackExchange.Redis/RedisBase.cs:line 54\n at StackExchange.Redis.RedisDatabase.Execute(字符串命令, ICollection`1 args,CommandFlags 标志)在 //src/StackExchange.Redis/RedisDatabase.cs:line 1204\n at StackExchange.Redis.RedisDatabase.Execute(字符串命令,对象[] args) 在 /_/src/StackExchange.Redis/RedisDatabase.cs:line 1200\n 在 deneme.Program.Main(String[] args) 在 /Users/serhatonal/Projects/deneme/deneme/Program.cs:23

之后我将脚本更改如下

        ConnectionMultiplexer muxer = ConnectionMultiplexer.Connect("127.0.0.1:6380");
        IDatabase conn = muxer.GetDatabase();

        conn.Execute("DEL","DB");

        conn.Execute("REDIsql.CREATE_DB","DB");
        conn.Execute("REDIsql.EXEC",B TEXT);");
        
        conn.Execute("REDIsql.CREATE_STATEMENT","INSERTINTOTABLE1STMT",?2)");

        conn.Execute("REDIsql.EXEC_STATEMENT","Value1" );
        conn.Execute("REDIsql.EXEC_STATEMENT",2,"Value2");

        var res = conn.Execute("REDIsql.EXEC","SELECT * FROM TABLE1");

执行 REDIsql.CREATE_STATEMENT 行时出现以下错误,如文档 https://redisql.redbeardlab.com/references/#redisqlexec_statement

中所述

System.ArgumentOutOfRangeException:“指定的参数超出了 有效值的范围。 (参数'命令'REDIsql.CREATE_STATEMENT' 超过 23 个字节的库限制')" 在 StackExchange.Redis.CommandBytes..ctor(String value) 中 //src/StackExchange.Redis/CommandBytes.cs:line 109\n at StackExchange.Redis.CommandMap.GetBytes(String command) in >//src/StackExchange.Redis/CommandMap.cs:line 181\n at >StackExchange.Redis.RedisDatabase.ExecuteMessage..ctor(CommandMap map,>Int32 db,CommandFlags flags,String command,ICollection1 args) in >/_/src/StackExchange.Redis/RedisDatabase.cs:line 3720\n at >StackExchange.Redis.RedisDatabase.Execute(String command,ICollection1 >args,CommandFlags flags) in >/ /src/StackExchange.Redis/RedisDatabase.cs:line 1203\n at >StackExchange.Redis.RedisDatabase.Execute(String command,Object[] args) >in //src/StackExchange.Redis/RedisDatabase.cs:line 1200\ n at >deneme.Program.Main(String[] args) in >/Users/serhatonal/Projects/deneme/deneme/Program.cs:23

在我们的实时场景中,我们有许多使用多个类型参数的 sql,因此继续使用包含字符串作为参数的 sql 并不优雅。

感谢任何帮助

解决方法

从错误消息来看,redisql 似乎不接受参数,因此:您可能需要自己内联这些值,注意避免 SQL 注入。这是模块供应商的话题。

关于 23 字节的限制:有趣的是,这是我第一次看到这个溢出,但是:是的,我们可以增加它。对不起。

,

来自 RediSQL 的 Simone。

所以,你几乎在任何事情上都是对的。

RediSQL V1 不支持向 EXEC 传递参数,这是我的错误,这是一个糟糕的设计。幸运的是,我们继续使用 RediSQL V2,它支持将参数传递给 EXEC。

您创建语句的解决方案是正确的。当您想多次重复相同的查询时,假设使用语句,每次使用不同的参数。

所以你肯定在一个好的轨道上。

第二个问题是由于StackExchange自身的限制。在这里,我们没什么可做的。

为了快速分配内存,他们将命令存储在 3 ulong 中:https://github.com/StackExchange/StackExchange.Redis/blob/main/src/StackExchange.Redis/CommandBytes.cs#L28

结果是 (3 * 8) - 1 = 23 字节,REDISQL.CREATE_STATEMENT 是 24 字节。不合适。

解决此问题的方法是将 REDISQL.CREATE_STATEMENT 重命名为 REDISQL.NEW_STATEMENT 之类的名称,您可以重命名 Redis 命令,在您的配置中添加如下内容:

rename-command REDISQL.CREATE_STATEMENT REDISQL.NEW_STATEMENT

我知道这是一个繁琐的过程,但这是我看到的唯一解决方案。

我真的建议改用 RediSQL V2 或 zeeSQL(https://zeesql.comhttps://doc.zeesql.com 中的文档)。

这将使这两个问题消失。

很抱歉没有提前回复,但我没有收到通知。我相信我现在可以修复它们。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。