0

我现在正在寻找一段时间没有找到解决我的问题的方法。如果当前不存在,我想在表中插入一个新行。我需要该新条目的自动递增键或现有条目的现有键。

另外我不清楚我的 INSERT 的返回值的想法,如果插入一列,值 = 1,如果该行存在怎么办?值 = 0 或 NULL 或 ?!

如果可能的话,我不想“批量插入”,我必须将这两个返回值用于下一个插入作为外键......或者有谁知道如何通过批量插入来完成这一切?

感谢所有可以提供帮助的人!!

系统:MS SQL 2012标准数据库,JAVA SE 1.6,sqljdbc4

这是我的代码,它给了我一个 SQLException:

    public long executeUpdateActionStatement(String sqlStatement, int autoGeneratedKeys) {

    ResultSet rs = null;
    Statement stmt = null;
    int rowCount = 0;
    try {
        connect();
        stmt = connect.createStatement();

        rowCount = stmt.executeUpdate(sqlStatement, autoGeneratedKeys);


        // if no new row is inserted, later I do a select to get the key
        if (rowCount < 1) 
            return -1;

        stmt.getGeneratedKeys();    /* This step throws the exception ! */
        if (rs.next()) {
            long id = rs.getLong(1);
            System.out.println(" !! ==---> ID: " + id + " | : " + sqlStatement);
            return id;
        }


    } catch (SQLFeatureNotSupportedException feature) {
        feature.printStackTrace();
        System.out.println("|| ---->>> Fehler: SQLFeatureNotSupportedException: " + sqlStatement);

    } catch (SQLServerException sqlse) {
        sqlse.printStackTrace();
        System.out.println("|| ---->>> Fehler: SQLServerException: " + sqlStatement);
    } catch (SQLException e) {
        e.printStackTrace();
        System.out.println("|| ---->>> Fehler: SQLException: " + sqlStatement);
    }

    finally {

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
    }

    return -1;

}

我得到的 SQLException:

    com.microsoft.sqlserver.jdbc.SQLServerException: Die Anweisung muss ausgeführt werden, bevor Ergebnisse abgerufen werden können.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getGeneratedKeys(SQLServerStatement.java:2040)

用英语讲:

    The statement must be executed before any results can be obtained.

SQL 语句:

    executeUpdateActionStatement("IF NOT EXISTS (SELECT GeoLocationId FROM GeoLocationCoordinates WHERE Longitude = " + longitude + 
    " AND Latitude = " + latitude + ") INSERT INTO GeoLocationCoordinates VALUES (" + longitude + ", " + latitude + ")", Statement.RETURN_GENERATED_KEYS); //Statement.RETURN_GENERATED_KEYS);

    executeUpdateActionStatement("IF NOT EXISTS (SELECT PlaceId FROM Places WHERE TwitterPlaceId = \'" + p.getId() + "\') INSERT INTO Places VALUES (" + 
            placeData + ")", Statement.RETURN_GENERATED_KEYS);

数据库表:

    /****** Object:  Table [dbo].[GeoLocationCoordinates]    Script Date: 16.08.2013 17:55:04 **************************************************************************/
    SET ANSI_NULLS ON
    GO

    SET QUOTED_IDENTIFIER ON
    GO

    CREATE TABLE [dbo].[GeoLocationCoordinates](
        [GeoLocationId] [bigint] IDENTITY(1,1) NOT NULL,
        [Longitude] [float] NOT NULL,
        [Latitude] [float] NOT NULL, CONSTRAINT [PK_GeoLocationCoordinates] PRIMARY KEY CLUSTERED (  [GeoLocationId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    GO

    /****** Object:  Table [dbo].[Places]    Script Date: 16.08.2013 17:57:16 **************************************************************************/
    SET ANSI_NULLS ON
    GO

    SET QUOTED_IDENTIFIER ON
    GO

    CREATE TABLE [dbo].[Places](
      [PlaceId] [bigint] IDENTITY(1,1) NOT NULL,
      [TwitterPlaceId] [nvarchar](255) NULL,
      [PlaceName] [nvarchar](255) NULL,
      [PlaceFullName] [nvarchar](255) NULL,
      [StreetAdress] [nvarchar](255) NULL,
      [Country] [nvarchar](255) NULL,
      [PlaceType] [nvarchar](255) NULL,
      [PlaceUrl] [nvarchar](255) NULL,
      [BoundingBoxType] [nvarchar](255) NULL,
      [CountryTwoLetterCode] [nchar](2) NULL,
     CONSTRAINT [PK_Places] PRIMARY KEY CLUSTERED 
    (
  [PlaceId] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    GO
4

2 回答 2

1

如果没有行受到影响,executeUpdate 返回 0 或受影响的行数。

您的代码中的哪一步引发了异常?

编辑2:好的,看起来合并会起作用。

PreparedStatement stmt = connection.prepareStatement(
        "merge table_1 t1 " +
        "using (select 'testvalue' as col1) t2 " +
        " on t1.col1 = t2.col1 " +
        " when not matched by target then " + 
        " insert (col1) values('testvalue'); "  
        ,Statement.RETURN_GENERATED_KEYS);

int out = stmt.executeUpdate();
System.out.println("Return:  " + out);  
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
    System.out.println("value:  " + rs.getLong(1));
}

如果目标表中不存在值“testvalue”,则将插入该值。如果插入,则返回值为 1,getGeneratedKeys 将返回新行的标识列值。如果确实存在,则两种方法都将返回 0。

于 2013-09-06T15:33:44.200 回答
0

这在语法上不正确,但给出了一个想法,只需在事务中使用范围标识来获取新密钥并在子表上使用它。事务中的 scrope 为您提供了您想要的数字。如果存在,您只需将找到的值的数量存储在其他代码中。理想情况下,可能可以在同一个过程中完成。

declare @returnvalue int


BEGIN TRANSACTION
INSERT INTO GeoLocationCoordinates(longitude,latitude)
values (@lat,@long)

SELECT @returnvalue = SCOPE_IDENTITY()

INSERT INTO childtable (field1,field2,parentkey)
VALUES (@field1,@field2,@returnvalue)
COMMIT TRANSACTION
于 2013-09-06T15:30:43.947 回答