Tencent / APIJSON

🏆 实时 零代码、全功能、强安全 ORM 库 🚀 后端接口和文档零代码,前端(客户端) 定制返回 JSON 的数据和结构 🏆 Real-Time coding-free, powerful and secure ORM 🚀 providing APIs and Docs without coding by Backend, and the returned JSON of API can be customized by Frontend(Client) users
http://apijson.cn
Other
17.27k stars 2.16k forks source link

[存储过程] 怎么调用sqlserver存储过程? #653

Open fengdu126 opened 11 months ago

fengdu126 commented 11 months ago

Description

看文档是可以调用存储过程,但试了很多次都是调用出错。

大家有试过调用sqlserver存储过程成功的吗,是不是还要在function表里面增加记录,能否提供一个简单的例子,谢谢!

调用json:

{     "User":{         "@limit":2,         "@offset":5,         "@procedure()":"testproc(@limit,@offset)"     }   }

或者:

{         "@limit":2,         "@offset":5,         "@procedure()":"testproc(@limit,@offset)"      }

后台显示错误的截图:

https://github.com/fengdu126/appokgo/blob/master/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20231220154209.png

提示:use of execute(string) method is not supported on this type of statement

存储过程是这样写的:

ALTER PROCEDURE [dbo].[testproc] (@limit int,@offset int)

AS BEGIN

select @limit+@offset as sumqty

END

在数据库里面执行这条语句:execute testproc 4,5 是可以正常执行返回结果没有问题

怀疑是不是不支持sqlserver的存储过程用法,后台转成了 execute(testproc 4,5)这样去调用了?从而导致语法错误

TommyLemon commented 11 months ago

只需要数据库有能访问的存储过程,不需要配置,按通用文档存储过程调用方式来调用。 还有问题就具体把参数和返回结果发出来,光几句话描述很难定位问题,大家也不想浪费时间来来回回一问一答地回复

fengdu126 commented 11 months ago

只需要数据库有能访问的存储过程,不需要配置,按通用文档存储过程调用方式来调用。 还有问题就具体把参数和返回结果发出来,光几句话描述很难定位问题,大家也不想浪费时间来来回回一问一答地回复

好的,我已补上了截图及调用参数和错误截图,帮看看是什么原因,谢谢!

fengdu126 commented 11 months ago

查了下后台生产的sql语句: 已生成 1 条 SQL execute startTime = 1703059140836 database = ; schema = ; sql = CALL "dbo".testproc(2,5)

sqlserver数据库的话正确应该是: CALL "dbo".testproc 2,5 或者 execute "dbo".testproc 2,5

参数不能加括号,请问这个怎么改?

fengdu126 commented 11 months ago

改成这样调用: { "@limit":2, "@offset":5, "@procedure()":"testproc @limit,@offset"
} 又提示函数命名不规范,不能通过。

TommyLemon commented 11 months ago

判断数据库为 SQL Server 时去掉括号

String s = (hasPrefix ? procedure.substring(ind + 1) : procedure);
if (isSQLServer()) {
  s = s.substring(1, s.length() - 1);
}

https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L4433-L4443

image
fengdu126 commented 11 months ago

判断数据库为 SQL Server 时去掉括号

String s = (hasPrefix ? procedure.substring(ind + 1) : procedure);
if (isSQLServer()) {
  s = s.substring(1, s.length() - 1);
}

https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L4433-L4443 image

改了还是提示错误:

已生成 1 条 SQL execute startTime = 1703125699443 database = ; schema = ; sql = CALL "dbo".testproc 2,5

2023-12-21 10:28:19.443: DemoSQLExecutor.DEBUG: getConnection config.getDatasource() = null java.sql.SQLException: Use of the execute(String) method is not supported on this type of statement.

改成EXECUTE 也不行:

已生成 1 条 SQL execute startTime = 1703125699443 database = ; schema = ; sql = EXECUTE "dbo".testproc 2,5

EXECUTE "dbo".testproc 2,5 这句sql在sqlserver执行器里面是可以执行的。

感觉虽然这里把括号去掉了,最后给数据库的语句还是execute()了,请帮看下这个怎么解决,谢谢!

fengdu126 commented 11 months ago

查了java通过jdbc驱动调用sqlserver存储过程的资料: https://www.cnblogs.com/dayday-study/archive/2012/05/09/2492651.html 如果带参数的话,好像还比较麻烦...

TommyLemon commented 11 months ago

APIJSON ORM 默认就是 ? 模板参数预编译调用,可以在 DemoSQLConfig 重写 isPrepared, return false 改成直接调用试试

fengdu126 commented 10 months ago

APIJSON ORM 默认就是 ? 模板参数预编译调用,可以在 DemoSQLConfig 重写 isPrepared, return false 改成直接调用试试

改了也是沒用,大佬能否用sqlserver测试下解决这个问题,现在sqlserver也跨平台了,实际应用挺多的,很多复杂的查询或者业务需要调用存储过程来解决。

TommyLemon commented 10 months ago

@fengdu126 目前我这边 M2 芯片 Mac 用 Docker 部署 SQLServer 碰到一些问题还没解决,你可以提供一个能在公网测试 SQLServer 的数据库给我吗?把 uri, username, password, version 发我邮箱 tommylemon@qq.com