Azure Synapse Spark池如何运行专用SQL池存储过程并查询数据?
Azure Synapse 两个常见技术问题解答
如何在Spark池中运行已在专用SQL池创建的存储过程
Spark池本身没有和专用SQL池共享存储过程的执行上下文,没法直接原生调用,需要通过JDBC通道发起调用,Synapse Spark环境默认已经内置了适配的SQL Server JDBC驱动,不用额外上传依赖,操作步骤如下:
- 准备连接信息:提前记录专用SQL池的端点地址、目标库名,优先使用工作区托管标识做鉴权,不要硬编码SQL账号密码在代码里,避免凭据泄露。
- 通过JDBC连接发起存储过程调用,不要用常规的
read.jdbc接口,那个接口只适配查询拉取场景,执行存储过程需要直接获取JDBC连接对象执行语句,参考PySpark示例代码:
# 替换成你自己环境的专用SQL池连接信息 jdbc_url = "jdbc:sqlserver://<你的专用SQL池端点>:1433;database=<目标库名>;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.sql.azuresynapse.net;loginTimeout=30;" conn_props = { "driver": "com.microsoft.sqlserver.jdbc.SQLServerDriver", "auth_type": "ActiveDirectoryMSI" } # 建立连接并执行存储过程,示例为带两个入参的存储过程 conn = spark._jvm.java.sql.DriverManager.getConnection(jdbc_url, conn_props["auth_type"], "") stmt = conn.createStatement() # 按实际存储过程的参数要求拼接EXEC语句即可 stmt.execute("EXEC dbo.your_sp_name @param1='test_val', @param2=100") # 如果存储过程返回结果集,可通过stmt.getResultSet()获取结果后转成Spark DataFrame做后续处理 # 用完记得关闭连接和语句对象,避免连接泄漏 stmt.close() conn.close()
踩坑提醒:别在Spark上下文的
%%sql单元格里直接写EXEC语句,Spark内置元存储识别不到专用SQL池的存储过程对象,会直接报对象不存在的错误。另外不要在调用的存储过程里开启跨库分布式事务,Spark侧无法承接专用SQL池的事务回滚逻辑,容易出现脏数据。
是否支持在Notebook中执行SQL查询访问专用SQL池内的数据
完全支持,目前有三种成熟的实现方式,可根据场景选择:
- 内置SQL magic直连:在Notebook单元格开头写
%%sql,在单元格顶部的连接下拉菜单选择目标专用SQL池,等连接建立完成后直接写标准SQL查询即可,查询结果会自动以表格形式渲染,支持一键导出、转成Spark DataFrame做后续处理,适合快速查数的临时分析场景。 - 原生Synapse连接器读取:这是性能最好的方式,做了专属优化,大表查询会自动下推算子,比通用JDBC性能高30%以上,调用方式简单,不需要手动写连接参数,参考代码:
# 直接读取专用SQL池的整表数据 df = spark.read.synapsesql("<专用SQL池名称>.<架构名>.<表名>") # 支持传入自定义查询做预过滤 df = spark.read.synapsesql( query="SELECT id,name,dt FROM dbo.user_log WHERE dt >= '2024-01-01'", database="<专用SQL池名称>" )
- 通用JDBC连接读取:和前面调用存储过程的JDBC逻辑一致,适合需要自定义连接参数、做复杂动态SQL拼接的场景,拉取的数据直接是Spark DataFrame,兼容所有Spark算子操作。
小提示:不管用哪种方式,都要提前给工作区托管标识授予专用SQL池对应的读/写权限,不然会报权限拒绝错误;跑大查询前记得确认专用SQL池的DWU配置足够,避免查询长时间排队。
内容的提问来源于stack exchange,提问作者darkstar
相关产品推荐
相关产品推荐

