Câu hỏi Làm thế nào để bạn nhận được các tham số đầu ra từ một thủ tục lưu sẵn trong Python?


Tôi đã googled xung quanh một chút, nhưng có lẽ tôi đã không đặt đúng câu thần chú vào hộp tìm kiếm.

Có ai biết làm thế nào để có được các thông số đầu ra từ một thủ tục được lưu trữ trong Python? Tôi đang sử dụng pymssql để gọi một thủ tục được lưu trữ, và tôi không chắc chắn về cú pháp chính xác để có được tham số đầu ra trở lại. Tôi không nghĩ rằng tôi có thể sử dụng bất kỳ mô-đun db khác kể từ khi tôi đang chạy này từ một hộp Linux để kết nối với một cơ sở dữ liệu mssql trên một máy chủ MS.

import pymssql

con = pymssql.connect(host='xxxxx',user='xxxx',password='xxxxx',database='xxxxx')

cur = con.cursor()

query = "EXECUTE blah blah blah"

cur.execute(query)
con.commit()
con.close()

10
2017-10-10 14:39


gốc




Các câu trả lời:


Tôi không phải là một chuyên gia về python nhưng sau một bản tóm tắt ngắn gọn về DB-API 2.0 Tôi tin rằng bạn nên sử dụng phương thức "callproc" của con trỏ như sau:

cur.callproc('my_stored_proc', (first_param, second_param, an_out_param))

Sau đó, bạn sẽ có kết quả trong giá trị trả về (của tham số ngoài) trong biến "an_out_param".


4
2017-10-10 15:59



Thật không may, tôi gặp lỗi này. Có vẻ như pymssql không có callproc. AttributeError: pymssqlCursor instance không có thuộc tính 'callproc' - projecktzero
Hãy thử tìm một trình điều khiển khác tương thích với DB-API 2.0 hơn. Bắt đầu ở đây - wiki.python.org/moin/SQL_Server - Milen A. Radev
Dường như nó bao gồm phần lớn giống như liên kết này: ramblings.timgolden.me.uk/2007/09/26/… Không ai trong số những người miễn phí / oss dường như hỗ trợ callproc hoặc không chạy trên Linux. Tôi có thể cần phải xem xét một giải pháp dịch vụ web. - projecktzero
Tôi nghĩ rằng tôi đọc rằng callproc không được thực hiện hiện tại cho SQL Server khi tôi googled xung quanh một chút về điều này. - Tomalak
Chỉ trong trường hợp ai đó nhìn thấy câu trả lời này, bạn phải chuyển đến callproc các tham số đầu ra được bọc như thế này: pymssql.output (int, -1) Như được mô tả ở đây: github.com/pymssql/pymssql/blob/… - jloria


Nếu bạn không thể hoặc không muốn sửa đổi thủ tục ban đầu và có quyền truy cập vào cơ sở dữ liệu, bạn có thể viết một thủ tục wrapper đơn giản có thể gọi từ python.

Ví dụ, nếu bạn có một thủ tục được lưu trữ như:

CREATE PROC GetNextNumber
   @NextNumber int OUTPUT
AS
...

Bạn có thể viết một wrapper như vậy mà có thể dễ dàng gọi từ python:

CREATE PROC GetNextNumberWrap
AS
    DECLARE @RNextNumber int
    EXEC GetNextNumber @RNextNumber
    SELECT @RNextNumber
GO

Sau đó, bạn có thể gọi nó từ python như vậy:

import pymssql
con = pymssql.connect(...)
cur = con.cursor()
cur.execute("EXEC GetNextNumberWrap")
next_num = cur.fetchone()[0]

2
2017-10-20 22:22



Tôi tự hỏi nếu bạn có thể làm điều đó mà không có sproc phụ trợ, chỉ với conn.execute ("DECLARE @RNextNumber int; EXEC GetNextNumber @RNextNumber out; SELECT @RNextNumber"). - Constantin


Nếu bạn thực hiện thủ tục của bạn sản xuất một bảng, bạn có thể sử dụng kết quả đó như là một thay thế cho params ra.

Vì vậy, thay vì:

CREATE PROCEDURE Foo (@Bar INT OUT, @Baz INT OUT) AS
BEGIN
   /* Stuff happens here */
   RETURN 0
END

làm

CREATE PROCEDURE Foo (@Bar INT, @Baz INT) AS
BEGIN
   /* Stuff happens here */
   SELECT @Bar Bar, @Baz Baz
   RETURN 0
END

1
2017-10-13 17:34





Dường như mọi thư viện dbapi python được triển khai trên đầu trang của freetds (pymssql, pyodbc, v.v.) sẽ không thể truy cập thông số đầu ra khi kết nối với Microsoft SQL Server 7 SP3 trở lên.

http://www.freetds.org/faq.html#ms.output.parameters


1
2017-10-20 21:32



Câu trả lời này đã lỗi thời, ít nhất là cho pymssql. - Gord Thompson


Tôi đã có thể nhận được một giá trị đầu ra từ một thủ tục lưu sẵn SQL bằng cách sử dụng Python. Tôi không thể tìm thấy trợ giúp tốt nhận được các giá trị đầu ra trong Python. Tôi đã tự tìm ra cú pháp Python, vì vậy tôi nghi ngờ điều này đáng được đăng ở đây:

import sys, string, os, shutil, arcgisscripting
from win32com.client import Dispatch
from adoconstants import *

#skip ahead to the important stuff

conn = Dispatch('ADODB.Connection')
conn.ConnectionString = "Provider=sqloledb.1; Data Source=NT38; Integrated Security = SSPI;database=UtilityTicket"
conn.Open()

#Target Procedure Example: EXEC TicketNumExists @ticketNum = 8386998, @exists output

Cmd = Dispatch('ADODB.Command')
Cmd.ActiveConnection = conn

Cmd.CommandType = adCmdStoredProc
Cmd.CommandText = "TicketNumExists"

Param1 = Cmd.CreateParameter('@ticketNum', adInteger, adParamInput)
Param1.Value = str(TicketNumber)
Param2 = Cmd.CreateParameter('@exists', adInteger, adParamOutput)

Cmd.Parameters.Append(Param1)
Cmd.Parameters.Append(Param2)

Cmd.Execute()

Answer = Cmd.Parameters('@exists').Value

1
2017-10-20 17:58





Bạn cũng có thể xem xét sử dụng SELECT thay vì EXECUTE. EXECUTE là (iirc) về cơ bản là một lệnh SELECT không thực sự lấy bất cứ thứ gì (chỉ làm cho các tác dụng phụ xảy ra).


0
2017-10-13 17:26





Bạn có thể thử định dạng lại query:

import pypyodc

connstring = "DRIVER=SQL Server;"\
             "SERVER=servername;"\
             "PORT=1043;"\
             "DATABASE=dbname;"\
             "UID=user;"\
             "PWD=pwd"

conn = pypyodbc.connect(connString)
cursor = conn.cursor()

query="DECLARE @ivar INT \r\n" \
      "DECLARE @svar VARCHAR(MAX) \r\n" \
      "EXEC [procedure]" \
      "@par1=?," \
      "@par2=?," \
      "@param1=@ivar OUTPUT," \
      "@param2=@svar OUTPUT \r\n" \
      "SELECT @ivar, @svar \r\n"
par1=0
par2=0
params=[par1, par2]
result = cursor.execute(query, params)
print result.fetchall()

[1]https://amybughunter.wordpress.com/tag/pypyodbc/


0
2017-11-16 11:49





Đây là cách tôi đã làm điều đó, chìa khóa là để khai báo tham số đầu ra đầu tiên:

import cx_Oracle as Oracle

conn = Oracle.connect('xxxxxxxx')
cur = conn.cursor()

idd = cur.var(Oracle.NUMBER)
cur.execute('begin :idd := seq_inv_turnover_id.nextval; end;', (idd,))
print(idd.getvalue())

0
2017-11-30 02:17