【问题标题】:Java Not Deleting the DB Data ProperlyJava 未正确删除数据库数据
【发布时间】:2021-05-06 21:19:01
【问题描述】:

我正在运行以下 java 代码。该代码的目的是擦除所有数据的数据库。当我在数据库上自行运行 SQL 部分时,它成功地擦除了它。但是,当我尝试通过它运行它时,构建成功但数据仍然存在。任何帮助将不胜感激。

package ignorethis;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class CleanDatabaseCCQA3 {

    // Connect to your database.
    // Replace server name, username, and password with your credentials
    public static void main(String[] args) {
        String connectionUrl =
                "jdbc:sqlserver://ignoreme;"
                        + "database=mydb;"
                        + "user=myuser;"
                        + "password=mypass;"
                        + "encrypt=true;"
                        + "trustServerCertificate=true;"
                        + "loginTimeout=30;";

        ResultSet resultSet = null;

        try (Connection connection = DriverManager.getConnection(connectionUrl);
             Statement statement = connection.createStatement();) {

            // Create and execute an SQL statement.
            String cleanSql = " DECLARE @tableName VARCHAR(200) SET @tableName='' WHILE EXISTS(SELECT T.table_name FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name WHERE (TC.constraint_Type ='Foreign Key'or TC.constraint_Type IS NULL) AND T.table_name NOT IN ('dtproperties','sysconstraints','syssegments')AND Table_type='BASE TABLE' AND T.table_name > @TableName) BEGIN SELECT @tableName=min(T.table_name) FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name WHERE (TC.constraint_Type ='Foreign Key'or TC.constraint_Type IS NULL) AND T.table_name NOT IN ('dtproperties','sysconstraints','syssegments') AND Table_type='BASE TABLE' AND T.table_name > @TableName EXEC('DELETE FROM '+@tablename) PRINT 'DELETE FROM '+@tablename END SET @TableName='' WHILE EXISTS(SELECT T.table_name FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name WHERE TC.constraint_Type ='Primary Key'AND T.table_name <>'dtproperties' AND Table_type='BASE TABLE' AND T.table_name > @TableName) BEGIN SELECT @tableName=min(T.table_name) FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name WHERE TC.constraint_Type ='Primary Key' AND T.table_name <>'dtproperties' AND Table_type='BASE TABLE' AND T.table_name > @TableName EXEC('DELETE FROM '+ @tableName) PRINT 'DELETE FROM '+ @tableName If EXISTS(SELECT * FROM information_schema.columns WHERE COLUMNPROPERTY(OBJECT_ID(QUOTENAME(table_schema)+'.'+ QUOTENAME(@tableName)), column_name,'IsIdentity')=1) BEGIN DBCC CHECKIDENT (@tableName, RESEED, 1) PRINT @tableName END END ";
            resultSet = statement.executeQuery(cleanSql);

            // Print results from select statement
            while (resultSet.next()) {
                System.out.println(resultSet.getString(2) + " " + resultSet.getString(3));
            }
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

这是上面运行的 sql 的可读性更高的版本。这应该有助于提供更多的背景信息。

DECLARE @tableName VARCHAR(200)  
SET @tableName=''  
WHILE EXISTS  
 (  
 --Find all child tables AND those which have no relations  
             SELECT T.table_name FROM INFORMATION_SCHEMA.TABLES T  
             LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC  
             ON T.table_name=TC.table_name  
             WHERE (TC.constraint_Type ='Foreign Key'or TC.constraint_Type IS NULL) AND  
             T.table_name NOT IN ('dtproperties','sysconstraints','syssegments')AND  
             Table_type='BASE TABLE' AND T.table_name > @TableName  
 )  
 BEGIN  
             SELECT @tableName=min(T.table_name) FROM INFORMATION_SCHEMA.TABLES T  
             LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC  
             ON T.table_name=TC.table_name  
             WHERE (TC.constraint_Type ='Foreign Key'or TC.constraint_Type IS NULL) AND  
             T.table_name NOT IN ('dtproperties','sysconstraints','syssegments') AND  
             Table_type='BASE TABLE' AND T.table_name > @TableName  
             --Truncate the table  
             EXEC('DELETE FROM '+@tablename)  
     PRINT 'DELETE FROM '+@tablename  
 END 

SET @TableName=''  
WHILE EXISTS  
(  
            --Find all Parent tables  
            SELECT T.table_name FROM INFORMATION_SCHEMA.TABLES T  
            LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC  
            ON T.table_name=TC.table_name  
            WHERE TC.constraint_Type ='Primary Key'AND T.table_name <>'dtproperties' AND  
            Table_type='BASE TABLE' AND T.table_name > @TableName  
)  
BEGIN  
            SELECT @tableName=min(T.table_name) FROM INFORMATION_SCHEMA.TABLES T  
            LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name  
            WHERE TC.constraint_Type ='Primary Key' AND T.table_name <>'dtproperties' AND  
            Table_type='BASE TABLE' AND T.table_name > @TableName  
  
            --DELETE the table  
            EXEC('DELETE FROM '+ @tableName)  
            PRINT 'DELETE FROM '+ @tableName  
            --Reset identity column  
            If EXISTS  
            (  
                        SELECT * FROM information_schema.columns  
                        WHERE COLUMNPROPERTY(OBJECT_ID(QUOTENAME(table_schema)+'.'+  
                        QUOTENAME(@tableName)), column_name,'IsIdentity')=1  
            )  
            BEGIN  
                        DBCC CHECKIDENT (@tableName, RESEED, 1)  
                        PRINT @tableName  
            END  
END 

进行下面建议的更改后,我得到以下堆栈跟踪

[[1;34mINFO[m] [1m--- [0;32mexec-maven-plugin:3.0.0:java[m [1m(default-cli)[m @ [36mmcautomation[0;1m ---[m
com.microsoft.sqlserver.jdbc.SQLServerException: Cannot invoke a rollback operation when the AutoCommit mode is set to "true".
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:226)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.rollback(SQLServerConnection.java:3086)
    at com.matrixcare.automation.utils.CleanDatabaseCCQA3.main(CleanDatabaseCCQA3.java:39)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:254)
    at java.lang.Thread.run(Thread.java:748)
[[1;33mWARNING[m] thread Thread[Abandoned connection cleanup thread,5,com.matrixcare.automation.utils.CleanDatabaseCCQA3] was interrupted but is still alive after waiting at least 15000msecs
[[1;33mWARNING[m] thread Thread[Abandoned connection cleanup thread,5,com.matrixcare.automation.utils.CleanDatabaseCCQA3] will linger despite being asked to die via interruption
[[1;33mWARNING[m] NOTE: 1 thread(s) did not finish despite being asked to  via interruption. This is not a problem with exec:java, it is a problem with the running code. Although not serious, it should be remedied.
[[1;33mWARNING[m] Couldn't destroy threadgroup org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup[name=com.matrixcare.automation.utils.CleanDatabaseCCQA3,maxpri=10]
[1;31mjava.lang.IllegalThreadStateException[m
    [1mat[m java.lang.ThreadGroup.destroy ([1mThreadGroup.java:778[m)
    [1mat[m org.codehaus.mojo.exec.ExecJavaMojo.execute ([1mExecJavaMojo.java:293[m)
    [1mat[m org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo ([1mDefaultBuildPluginManager.java:137[m)
    [1mat[m org.apache.maven.lifecycle.internal.MojoExecutor.execute ([1mMojoExecutor.java:210[m)
    [1mat[m org.apache.maven.lifecycle.internal.MojoExecutor.execute ([1mMojoExecutor.java:156[m)
    [1mat[m org.apache.maven.lifecycle.internal.MojoExecutor.execute ([1mMojoExecutor.java:148[m)
    [1mat[m org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject ([1mLifecycleModuleBuilder.java:117[m)
    [1mat[m org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject ([1mLifecycleModuleBuilder.java:81[m)
    [1mat[m org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build ([1mSingleThreadedBuilder.java:56[m)
    [1mat[m org.apache.maven.lifecycle.internal.LifecycleStarter.execute ([1mLifecycleStarter.java:128[m)
    [1mat[m org.apache.maven.DefaultMaven.doExecute ([1mDefaultMaven.java:305[m)
    [1mat[m org.apache.maven.DefaultMaven.doExecute ([1mDefaultMaven.java:192[m)
    [1mat[m org.apache.maven.DefaultMaven.execute ([1mDefaultMaven.java:105[m)
    [1mat[m org.apache.maven.cli.MavenCli.execute ([1mMavenCli.java:956[m)
    [1mat[m org.apache.maven.cli.MavenCli.doMain ([1mMavenCli.java:288[m)
    [1mat[m org.apache.maven.cli.MavenCli.main ([1mMavenCli.java:192[m)
    [1mat[m sun.reflect.NativeMethodAccessorImpl.invoke0 ([1mNative Method[m)
    [1mat[m sun.reflect.NativeMethodAccessorImpl.invoke ([1mNativeMethodAccessorImpl.java:62[m)
    [1mat[m sun.reflect.DelegatingMethodAccessorImpl.invoke ([1mDelegatingMethodAccessorImpl.java:43[m)
    [1mat[m java.lang.reflect.Method.invoke ([1mMethod.java:498[m)
    [1mat[m org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced ([1mLauncher.java:289[m)
    [1mat[m org.codehaus.plexus.classworlds.launcher.Launcher.launch ([1mLauncher.java:229[m)
    [1mat[m org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode ([1mLauncher.java:415[m)
    [1mat[m org.codehaus.plexus.classworlds.launcher.Launcher.main ([1mLauncher.java:356[m)

【问题讨论】:

  • 你的Java程序输出到标准输出的是什么?

标签: java sql-server


【解决方案1】:

添加commit 以提交更改(删除)

...
    while (resultSet.next()) {
        System.out.println(resultSet.getString(2) + " " + resultSet.getString(3));
    }
    connection.commit();
}
catch (SQLException e) {
    e.printStackTrace();
    connection.rollback();
}
...

您也应该使用try-with-resource 作为ResultSet

// ResultSet resultSet = null;

try (Connection connection = DriverManager.getConnection(connectionUrl);
     Statement statement = connection.createStatement();) {

    // Create and execute an SQL statement.
    String cleanSql = " DECLARE @tableName VARCHAR(200) SET @tableName='' WHILE EXISTS(SELECT T.table_name FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name WHERE (TC.constraint_Type ='Foreign Key'or TC.constraint_Type IS NULL) AND T.table_name NOT IN ('dtproperties','sysconstraints','syssegments')AND Table_type='BASE TABLE' AND T.table_name > @TableName) BEGIN SELECT @tableName=min(T.table_name) FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name WHERE (TC.constraint_Type ='Foreign Key'or TC.constraint_Type IS NULL) AND T.table_name NOT IN ('dtproperties','sysconstraints','syssegments') AND Table_type='BASE TABLE' AND T.table_name > @TableName EXEC('DELETE FROM '+@tablename) PRINT 'DELETE FROM '+@tablename END SET @TableName='' WHILE EXISTS(SELECT T.table_name FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name WHERE TC.constraint_Type ='Primary Key'AND T.table_name <>'dtproperties' AND Table_type='BASE TABLE' AND T.table_name > @TableName) BEGIN SELECT @tableName=min(T.table_name) FROM INFORMATION_SCHEMA.TABLES T LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON T.table_name=TC.table_name WHERE TC.constraint_Type ='Primary Key' AND T.table_name <>'dtproperties' AND Table_type='BASE TABLE' AND T.table_name > @TableName EXEC('DELETE FROM '+ @tableName) PRINT 'DELETE FROM '+ @tableName If EXISTS(SELECT * FROM information_schema.columns WHERE COLUMNPROPERTY(OBJECT_ID(QUOTENAME(table_schema)+'.'+ QUOTENAME(@tableName)), column_name,'IsIdentity')=1) BEGIN DBCC CHECKIDENT (@tableName, RESEED, 1) PRINT @tableName END END ";
    // resultSet = statement.executeQuery(cleanSql);

    // Print results from select statement
    try (ResultSet resultSet = statement.executeQuery(cleanSql)) {
        while (resultSet.next()) {
            System.out.println(resultSet.getString(2) + " " + resultSet.getString(3));
        }
        connection.commit();
    }
    catch (SQLException e) {
        connection.rollback();
        throw e;
    }
}
catch (SQLException e) {
    e.printStackTrace();
}

【讨论】:

  • 进行这些更改后,我将在上面添加以下堆栈跟踪
  • Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 放在 main 方法的开头。确保为 SQLServer 使用最新的 JDBC 驱动程序。
  • 我目前正在使用 9.2.1jre15 maven 依赖项,并且在添加该行时遇到了 ClassNotFound 异常。
  • @Tango-Dust,您使用最新版本的 Java 和 JDBC。文档在这里:docs.microsoft.com/en-us/sql/connect/jdbc/… 我不明白你为什么得到ClassNotFoundException
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
  • 1970-01-01
  • 2012-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-17
相关资源
最近更新 更多