代码之家  ›  专栏  ›  技术社区  ›  Lukas Eder

无法通过SQL数据仓库上的JDBC获取生成的密钥

  •  4
  • Lukas Eder  · 技术社区  · 6 年前

    我的Azure SQL数据仓库数据库中有一个这样的表:

    CREATE TABLE t_identity (
      id INTEGER IDENTITY (1, 1) NOT NULL,
      val INTEGER
    )
    

    现在,使用JDBC,我想插入一行并获取生成的标识值。这将在SQL Server和大多数其他数据库中工作:

    try (Connection c = DriverManager.getConnection(url, properties);
        Statement s = c.createStatement()) {
    
        s.executeUpdate("insert into t_identity (val) values (1)",
            Statement.RETURN_GENERATED_KEYS);
        try (ResultSet rs = s.getGeneratedKeys()) {
            while (rs.next())
                System.out.println(rs.getObject(1));
        }
    }
    

    Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: 'SCOPE_IDENTITY' is not a recognized built-in function name.
        at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:264)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1585)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(SQLServerStatement.java:876)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement$StmtExecCmd.doExecute(SQLServerStatement.java:776)
        at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7385)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2750)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:235)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:210)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeUpdate(SQLServerStatement.java:2060)
        at SQLServer.main(SQLServer.java:65)
    

    其他方法(例如。 executeUpdate(String, String[])

    我知道SQL数据仓库不支持 SCOPE_IDENTITY() and similar functions

    <dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
        <version>6.5.2.jre8-preview</version>
    </dependency>
    

    但有办法吗?

    笔记:

    2 回复  |  直到 6 年前
        1
  •  0
  •   Dan Bracuk    6 年前

    解决方法是添加到insert查询,然后选择id。

    insert into t_identity
    (val)
    select 'my value'
    where not exists
    (
    select 1
    from t_identity
    where val = 'my value'
    )
    
    select id
    from t_dan_identity
    where val = 'my value'
    
        2
  •  0
  •   Ron Dunn    6 年前

    您能更详细地描述一下您的业务用例吗?如果你在使用JOOQ,我认为你可能在技术上不匹配。

    Azure SQL数据仓库不适用于事务性工作负载。如果JOOQ只是维护一些引用行,那么我不认为有问题,但是如果它是您的主要数据加载策略,那么您不会得到好的结果。

    以下是一些可能有帮助的阅读资料:

    用例和反模式: https://blogs.msdn.microsoft.com/sqlcat/2017/09/05/azure-sql-data-warehouse-workload-patterns-and-anti-patterns/

    解决方案模型(滚动到图表): https://azure.microsoft.com/en-us/services/sql-data-warehouse/

    数据加载最佳实践: https://docs.microsoft.com/en-us/azure/sql-data-warehouse/guidance-for-loading-data

    数据加载模式和策略: https://blogs.msdn.microsoft.com/sqlcat/2017/05/17/azure-sql-data-warehouse-loading-patterns-and-strategies/