注册 登录
编程论坛 VFP论坛

请教关于VFP执行SQL SERVER有参数的存储过程

fanjinyu9108 发布于 2024-06-08 19:36, 384 次点击
SQLSERVER的存储过程语句如下:
程序代码:
CREATE PROCEDURE sb_query
    @c_sb_bm NVARCHAR(30),
    @c_lb1 NVARCHAR(30)
AS
BEGIN
    SELECT * FROM shebei
    WHERE sb_bm=@c_sb_bm and zl_id in (select id from shebei_zl where lb1=@c_lb1)
END


vfp执行过程语句如下:
cs_sb_bm="zhijiang"
cs_lb1="mijiu"
str_shebei=SQLEXEC(con,"EXEC sb_query @c_sb_bm=?cs_sb_bm,@c_lb1=?cs_lb1","shebei")


SQLSERVER的存储过程没有问题,但是VFP执行有问题,不能通过,但是我也不知道怎么写,恳请师傅们帮忙指正下
11 回复
#2
fanjinyu91082024-06-08 20:02
我再把存储过程的完整代码发下:
程序代码:
USE [yksb]
GO
/****** Object:  StoredProcedure [dbo].[sb_query]    Script Date: 2024/6/8 19:59:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sb_query]
    @c_sb_bm NVARCHAR(30),
    @c_lb1 NVARCHAR(30)
AS
BEGIN
    SELECT * FROM shebei
    WHERE sb_bm=@c_sb_bm and zl_id in (select id from shebei_zl where lb1=@c_lb1)
END
#3
fanjinyu91082024-06-09 14:37
问题解决了,在VFP执行的时候把EXEC sb_query @c_sb_bm=?cs_sb_bm,@c_lb1=?cs_lb1 改成EXEC sb_query ?cs_sb_bm,?cs_lb1就可以了
#4
fanjinyu91082024-06-09 14:42
但是接下来我想把存储过程的语句改复杂点,却失败了,师傅们能否帮忙看下,
select * from (SELECT *,shebei_zl.lb1,shebei_zl.lb2,shebei_zl.lb3,shebei_zl.zzs FROM shebei left join shebei_zl on shebei.zl_id=shebei_zl.id) where sb_bm=@c_sb_bm and lb1=@c_lb1
#5
fanjinyu91082024-06-09 14:52
改成如下还是不行:
SELECT *,shebei_zl.lb1,shebei_zl.lb2,shebei_zl.lb3,shebei_zl.zzs FROM shebei left join shebei_zl on shebei.zl_id=shebei_zl.id where shebei.sb_bm=@c_sb_bm and shebei_zl.lb1=@c_lb1
#6
csyx2024-06-09 16:30
* 没指定是哪个表的所有列吧,这样呢?

SELECT A.*, B.lb1, B.lb2, B.lb3, B.zzs
FROM shebei A
left join shebei_zl B on A.zl_id = B.id
where A.sb_bm = @c_sb_bm and B.lb1 = @c_lb1

#7
fanjinyu91082024-06-10 06:46
感谢版主csyx,这个问题解决了,又有新的问题了,现在我在存储过程查询了2个表,VFP端怎么接受呢?我试了以下,没有成功,代码如下:
str_shebei=SQLEXEC(con,"EXEC sb_query ?cs_sb_bm,?cs_lb1","shebei","shebei_cs")

#8
csyx2024-06-10 07:37
返回多个表时,从第二个开始的命名自动依次为第一个表后面加序号,例如:

sqlexec(con, "select '第1个表'; select '第二个表'", "result")
执行后返回的两个临时表别名分别为 result 和 result1;若返回多个表,则后面依次为 result2, result3 。。。

也就是说,只允许你指定第一个临时表的别名,后面的临时表 vfp 自动命名

[此贴子已经被作者于2024-6-10 07:42编辑过]

#9
fanjinyu91082024-06-10 13:24
版主,您好,您上面这句没有执行存储过程的语句啊,我加上存储过程,用以下的语句,但是过不了
str_shebei=SQLEXEC(con,"EXEC sb_query ?cs_sb_bm,?cs_lb1","select '第1个表'; select '第二个表'", "result")
#10
csyx2024-06-10 17:44
以下是引用fanjinyu9108在2024-6-10 13:24:29的发言:
str_shebei=SQLEXEC(con,"EXEC sb_query ?cs_sb_bm,?cs_lb1","select '第1个表'; select '第二个表'", "result")

至少应该这样才可能出结果:
SQLEXEC(con,"EXEC sb_query ?cs_sb_bm,?cs_lb1; select '第2个表'; select '第三个表'", "result")

再说了,返回多个结果集的功能应该是在你的 sb_query 中实现,而不是由调用方决定,例如
sql server 端:
程序代码:
CREATE PROCEDURE sb_query
    @c_sb_bm NVARCHAR(30),
    @c_lb1 NVARCHAR(30)
AS
BEGIN
    SELECT * FROM shebei
    WHERE sb_bm=@c_sb_bm and zl_id in (select id from shebei_zl where lb1=@c_lb1);
    /* 再加上其他需要同时返回的查询结果 */
    select getdate();
    select newid();
END

vfp端:
程序代码:
cs_sb_bm="zhijiang"
cs_lb1="mijiu"
SQLEXEC(con,"EXEC sb_query ?cs_sb_bm,?cs_lb1", "result")
*- 当然,这样也是可以的,只是执行效率会比在存储过程中完成差很多
*-- SQLEXEC(con,"EXEC sb_query ?cs_sb_bm,?cs_lb1; select '第n个表'; select '第n+1个表'", "result")




[此贴子已经被作者于2024-6-10 17:46编辑过]

#11
fanjinyu91082024-06-11 07:27
非常感谢版主的解答,您在上面说只是执行效率会比在存储过程中完成差很多,这个我还是不怎么理解,这不就是在执行存储过程吗?我把存储过程的代码和VFP代码复制过来,您看下执行效率会低下吗?
BEGIN
    SELECT *,shebei_zl.lb1,shebei_zl.lb2,shebei_zl.lb3,shebei_zl.zzs FROM shebei left join shebei_zl on shebei.zl_id=shebei_zl.id where shebei.sb_bm=@c_sb_bm and shebei_zl.lb1= @c_lb1 and shebei_zl.lb2= @c_lb2  and shebei_zl.lb3= @c_lb3
    select * from shebei_zl
END

以下是VFP端的,按照您的方法改的,已经运行成功了
SQLEXEC(con,"EXEC sb_query ?cs_sb_bm,?cs_lb1; select '第2个表'", "result")


#12
csyx2024-06-11 16:37
简单且小数据量的测试是看不出来的,储存过程的好处之一是预编译,更重要的是可以重用执行计划

我意思是 select '第2个表' 这句(如果是更复杂的查询)应该放在 sql 端的 sb_query 存储过程中,而不是在 vfp 中作为第二查询

[此贴子已经被作者于2024-6-11 17:05编辑过]

1