【问题标题】:Spark JDBC SQL connector "SELECT INTO" StatementSpark JDBC SQL 连接器“SELECT INTO”语句
【发布时间】:2021-06-10 06:56:00
【问题描述】:

我正在尝试从 SQL Server 读取数据。由于某些要求,我需要使用SELECT INTO 语句创建一个临时表,该表将在查询中进一步使用。但是当我运行查询时,出现以下错误

com.microsoft.sqlserver.jdbc.SQLServerException:关键字“INTO”附近的语法不正确

我的问题是,Spark SQL 连接器是否允许使用 SELECT INTO 语句?

这是一个示例查询和代码

    drivers = {"mssql": "com.microsoft.sqlserver.jdbc.SQLServerDriver"}
    sparkDf = spark.read.format("jdbc") \
        .option("url", connectionString) \
        .option("query", "SELECT * INTO #TempTable FROM Table1") \
        .option("user", username) \
        .option("password", password) \
        .option("driver",  "com.microsoft.sqlserver.jdbc.SQLServerDriver") \
        .load()

【问题讨论】:

    标签: sql-server apache-spark pyspark apache-spark-sql mssql-jdbc


    【解决方案1】:

    这是因为司机正在做额外的事情,这妨碍了你。更明确地说,问题是documented here。这是您正在使用的“查询”选项的该页面的文档:

    用于将数据读入 Spark 的查询。指定的查询 将被加括号并用作 FROM 子句中的子查询。火花 还将为子查询子句分配一个别名。例如,火花 将向 JDBC Source 发出以下形式的查询。

    SELECT FROM () spark_gen_alias

    以下是使用此选项时的一些限制。

    It is not allowed to specify dbtable and query options at the same time.
    It is not allowed to specify query and partitionColumn options at the same time. When specifying partitionColumn option is required, the
    

    可以使用 dbtable 选项指定子查询并分区 列可以使用作为一部分提供的子查询别名来限定 数据库表。 例子: spark.read.format("jdbc") .option("url", jdbcUrl) .option("query", "select c1, c2 from t1") .load()

    本质上,驱动程序围绕您的代码放置的包装器会导致问题。而且由于它们的包装器以SELECT * FROM ( 开头并以) spark_generated_alias 结尾,因此您在如何“突破”它并仍然执行您想要的语句方面非常有限。

    我是这样做的。

    我将它分成 3 个单独的查询,因为普通 (#) 和全局 (##) 临时表不起作用(驱动程序在每次查询后断开连接)。

    查询 1:

    SELECT 1 AS col) AS tbl; --terminates the "SELECT * FROM (" the driver prepends
    
    --Write whatever Sql you want, then select into a new "real" table.
    --E.g. here's your example, but with a "real" table.
    SELECT * INTO _TempTable FROM Table1;
    
    SELECT 1 FROM (SELECT 1 AS col --and the driver will append ") spark_generated_alias". The driver ignores all result-sets but the first.
    

    查询 2:

    SELECT * FROM _TempTable;
    

    查询 3(在完成 DataFrame 之后才能运行它):

    SELECT 1 AS col) AS tbl; --terminates the "SELECT * FROM (" the driver prepends
    
    DROP TABLE IF EXISTS _TempTable;
    
    SELECT 1 FROM (SELECT 1 AS col --and the driver will append ") spark_generated_alias". The driver ignores all result-sets but the first.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      • 2021-01-19
      • 1970-01-01
      • 1970-01-01
      • 2014-02-07
      • 2016-06-21
      相关资源
      最近更新 更多