如何执行存储为字符串变量的Spark SQL多行查询?
问题分析与解决方案
你遇到的核心问题是只读取了SQL文件的第一行,导致传入spark.sql()的是不完整的SQL语句,自然触发了ParseException(SQL未写完就到了末尾)。结合你的Spark 2.1和Scala 2.11环境,给你以下具体修正方案:
1. 正确拼接多行SQL内容
你的代码里用hiveInsertIntoTable(0).mkString只取了SQL文件的第一行,完全忽略了后续449行内容。正确的做法是把所有行拼接成完整的SQL语句:
val hiveInsertIntoTable = spark.read.text(fileQuery).collect() // 将所有行拼接成完整的SQL字符串 val actualQuery = hiveInsertIntoTable.map(_.mkString).mkString("\n") println(actualQuery) // 现在打印的是完整的450行SQL
2. 移除SQL末尾的分号
Spark SQL执行时不需要语句末尾的分号,多余的分号可能会引发解析错误,所以可以在拼接后去掉末尾的分号:
// 去掉末尾的分号(如果存在) val cleanedQuery = actualQuery.stripSuffix(";").trim spark.sql(cleanedQuery)
完整修正后的代码
val hiveInsertIntoTable = spark.read.text(fileQuery).collect() hiveInsertIntoTable.foreach(println) val actualQuery = hiveInsertIntoTable.map(_.mkString).mkString("\n") println(actualQuery) spark.sql(s"truncate table $tableTruncate") // 清理并执行完整SQL val cleanedQuery = actualQuery.stripSuffix(";").trim spark.sql(cleanedQuery)
为什么之前的方法无效?
spark.read.text(fileQuery)会把文件按行读取,每一行对应一个Row对象,collect()返回的是包含所有行的Array[Row]。你之前只取了数组的第一个元素,相当于只拿到了SQL的第一行,后续内容都被忽略,导致SQL不完整。- 用三重引号包裹变量无效,是因为变量本身就是不完整的SQL,三重引号只是字符串字面量的写法,无法补全缺失的内容。
内容的提问来源于stack exchange,提问作者javadev
相关产品推荐
相关产品推荐

