Spark JDBC连接SQL Server使用SELECT INTO报错是否支持该语法
问题原因
Spark SQL JDBC连接器本身不限制SQL Server的SELECT INTO语法,报错是因为spark.read.jdbc的query参数要求传入的语句必须返回可读取的结果集,而SELECT INTO属于DDL写操作,执行后只会创建临时表、不会返回查询结果,不符合read接口的预期,因此触发语法报错。
解决方案
方案1:需要在SQL Server端创建临时表后直接读取临时表数据
你可以把建表+查询的多段SQL合并为同一个query参数值,同时加上SET NOCOUNT ON避免中间执行消息干扰结果集返回,示例代码如下:
drivers = {"mssql": "com.microsoft.sqlserver.jdbc.SQLServerDriver"} sparkDf = spark.read.format("jdbc") \ .option("url", connectionString) \ .option("query", "SET NOCOUNT ON; SELECT * INTO #TempTable FROM Table1; SELECT * FROM #TempTable") \ .option("user", username) \ .option("password", password) \ .option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver") \ .load()
执行后临时表会在当前JDBC会话的SQL Server端创建,同时Spark会拿到最终SELECT返回的结果集。
方案2:仅需要在Spark侧使用临时表做后续查询
如果不需要在SQL Server侧保留临时表,完全可以直接读取原表数据后注册为Spark的临时视图,性能更高也不需要占用SQL Server侧资源,示例代码如下:
drivers = {"mssql": "com.microsoft.sqlserver.jdbc.SQLServerDriver"} # 直接读取原表数据 sparkDf = spark.read.format("jdbc") \ .option("url", connectionString) \ .option("dbtable", "Table1") \ .option("user", username) \ .option("password", password) \ .option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver") \ .load() # 注册为Spark临时视图,后续可用Spark SQL直接查询 sparkDf.createOrReplaceTempView("TempTable")
方案3:不需要返回数据,仅要执行SELECT INTO建表
如果你不需要读取任何数据,只是要在SQL Server端执行建表操作,应该直接获取JDBC连接执行语句,不要用Spark的read接口,示例代码如下:
from py4j.java_gateway import java_import # 获取JDBC连接 java_import(spark._jvm, "java.sql.DriverManager") conn = spark._jvm.DriverManager.getConnection(connectionString, username, password) stmt = conn.createStatement() # 执行SELECT INTO语句 stmt.execute("SELECT * INTO #TempTable FROM Table1") # 关闭连接 stmt.close() conn.close()
内容的提问来源于stack exchange,提问作者user3104078
相关产品推荐
相关产品推荐

