iT邦幫忙

0

[已解決] python sql 預存程序 多個結果集 & 單個返回值

  • 分享至 

  • xImage

各位大大好,小弟目前在練習sql預存程序遇到以下狀況

  1. 如果預存內有兩個sql結果集,該怎麼接收?
  2. 如果預存內有單獨的值,該怎麼接收?
-- sql創建預存程序
CREATE PROCEDURE  usp_testProc
@key NVARCHAR(10) = 'a'
@result int output
AS
    set @result = '100'
    SELECT * FROM [Test].[dbo].[test]
    WHERE [testTest] = @key
    SELECT * FROM [Test].[dbo].[test]
GO

使用sql操作如下

BEGIN
    declare @result int
    EXEC usp_testProc '1', @result output
    print(@result)
END

https://ithelp.ithome.com.tw/upload/images/20210630/20132538nZHXrtIxC9.png
https://ithelp.ithome.com.tw/upload/images/20210630/20132538DLDGhXJVN9.png

如上圖所示,小弟希望在python中取得

  1. 2個結果集
  2. @result 數值100
conn = pymssql.connect(
    server = 'ip',
    user = 'testUser',
    password = 'testPassword',
    database = 'test',
    charset = 'utf8'
)
cursor = conn.cursor(as_dict = True)

# 請問此處該如何撰寫,才能得到以上
# 小弟已能夠正常獲取單個結果集
# cursor.execute(...)
# cursor.callproc('usp_testProc', ('1',))

再請各位大大們不吝指教!!

----------------------------

解決方法,在不同的資料庫中有部分DB支持返回多個結果集,
於是再調用時使用

print(cursor.fetchall()) # 第一個結果集

cursor.nextset() # 將光標移至下一個結果集,如果沒有則會報錯

print(cursor.fetchall()) # 因為光標已移至下一個,所以得到第二個結果集

以上,感謝回答的兩位大大。

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
japhenchen
iT邦超人 1 級 ‧ 2021-06-30 16:39:11
最佳解答
    conn = pymssql.connect('11.22.33.44', 'super', 'iamsuper', 'database')
    cursor = conn.cursor(as_dict=False)
    cursor.execute(f"exec sp_data '{param1}','{param2}'")
    data = cursor.fetchall()
    print(data) # 到這裡,data已經是list(list())的型態了
            
       
看更多先前的回應...收起先前的回應...

回japhenchen大大,

我個人的部分也是做到這邊,我能夠取得第一個結果集,
但沒辦法取得第二個Select返回結果集,

這是我在練習中遇到的問題,我就想著如果一個預存能夠返回兩個結果集,雖然可能沒關係,但我能否做到。

還是說這本就是sql預設的行為呢?

預存程序內的第二個結果集 & 文本結果該如何獲取?

再請大大指教感謝!!

兩個結果集之間有關連嗎?

回japhenchen大大,

兩個結果集之間無關連,返回值也是測試用,
這個部份僅是練習中遇到的想法。

再請大大指教,感謝感謝!!

mysql的多output的方法,參考看看

connection = pymysql.connect(host="host", user="user", password="pass", db="schema")  # etc.

with connection.cursor() as cursor:
    cursor.callproc("procedure_name", ("foo", "bar"))  # pass procedure parameters as a tuple
    while True:  # loop while there are result sets
        if cursor.rowcount:  # make sure there are actually results in the current set
            result_set = cursor.fetchall()  # or cursor.fetchone() / cursor.fetchmany()
            # do whatever you want with the result_set, store it in a dict if you want
        # after done processing the current result set, move on to the next
        if not cursor.nextset():  # switch to the next result set, if available...
            break  # exit the loop if not

感謝大大!!
看了您的代碼發現了個關鍵 nextset(),
於是查詢了一下!!
解決了感謝感謝!!

1
jim31322
iT邦新手 5 級 ‧ 2021-06-30 17:32:32
-- sql創建預存程序
CREATE PROCEDURE  usp_testProc
@key NVARCHAR(10) = 'a'
@result int output
AS
    set @result = '100'
    SELECT * FROM [Test].[dbo].[test]
    WHERE [testTest] = @key
    SELECT * FROM [Test].[dbo].[test]
GO

@result int output 是你的 procedure 輸出的資料
是否你要再宣告兩個輸出的參數,並把結果集放入,例如

CREATE PROCEDURE  usp_testProc
@key NVARCHAR(10) = 'a'
@result int output
@cursor1 cursor output
@cursor2 cursor output
AS
    set @result = '100'
    SELECT * INTO cursor1 FROM [Test].[dbo].[test]
    WHERE [testTest] = @key
    SELECT * INTO cursor2 FROM [Test].[dbo].[test]
GO

以上是我的想法,正確語法你需要去查一下

回@jim31322大大,

我大概明白您的意思,小弟嘗試看看。

感謝感謝 !!

我要發表回答

立即登入回答