如何在AWS EMR PySpark Notebook中通过JDBC调用SQL Server存储过程?
在PySpark中通过JDBC调用SQL Server存储过程的正确语法
问题场景
已确认JDBC驱动和常规查询连接正常,但调用SQL Server存储过程时出现语法错误:
- 使用
call zzzTestProcedure报错:com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near ')' - 使用
exec zzzTestProcedure报错:com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near the keyword 'exec'
原代码片段:
%%configure -f { "conf": { "spark.jars": "s3://mv-prod-emr-scripts/jars/mssql-jdbc-12.8.1.jre8.jar" } } str_username = "<user>" str_password = "<password>" str_jdbc_warehouse_url = "jdbc:sqlserver://<IP>:1433;databaseName=<Database>" str_warehouse_query = "call zzzTestProcedure" df = spark.read \ .format("jdbc") \ .option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver") \ .option("trustServerCertificate", "true") \ .option("url", str_jdbc_warehouse_url) \ .option("query", str_warehouse_query) \ .option("user", str_username) \ .option("password", str_password) \ .load()
解决方案
方法1:使用dbtable选项配合{call ...}语法(推荐)
Spark JDBC的dbtable支持直接指定存储过程调用的标准JDBC语法,即使无参数也需要添加括号:
df = spark.read \ .format("jdbc") \ .option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver") \ .option("trustServerCertificate", "true") \ .option("url", str_jdbc_warehouse_url) \ .option("dbtable", "{call zzzTestProcedure()}") \ .option("user", str_username) \ .option("password", str_password) \ .load()
方法2:修正query选项的语法
如果必须使用query选项,需注意两点:
CALL语句必须带括号(即使无参数)- 若存储过程返回额外结果集(如影响行数计数),需添加
SET NOCOUNT ON抑制干扰
示例代码:
# 无额外结果集的情况 str_warehouse_query = "CALL zzzTestProcedure()" # 有额外结果集的情况 str_warehouse_query = """ SET NOCOUNT ON; EXEC zzzTestProcedure; """ df = spark.read \ .format("jdbc") \ .option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver") \ .option("trustServerCertificate", "true") \ .option("url", str_jdbc_warehouse_url) \ .option("query", str_warehouse_query) \ .option("user", str_username) \ .option("password", str_password) \ .load()
内容的提问来源于stack exchange,提问作者Vercinegetorix
相关产品推荐
相关产品推荐

