Files
workspace/code/fms/.tmp-fkcheck/DropFks.java
T
2026-08-21 23:06:56 +08:00

113 lines
5.2 KiB
Java

import java.io.FileInputStream;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class DropFks {
static class Fk {
String name, schema, parentTable, refTable, delAction, updAction;
List<String[]> cols = new ArrayList<>(); // {parentCol, refCol}
}
public static void main(String[] args) throws Exception {
Properties props = new Properties();
try (FileInputStream in = new FileInputStream(args[0])) { props.load(in); }
String url = props.getProperty("url");
String user = props.getProperty("username");
String pass = props.getProperty("password");
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
try (Connection conn = DriverManager.getConnection(url, user, pass)) {
conn.setAutoCommit(false);
List<Fk> fks = new ArrayList<>();
String sql =
"SELECT fk.name AS fk_name, " +
"OBJECT_SCHEMA_NAME(fk.parent_object_id) AS sch, " +
"OBJECT_NAME(fk.parent_object_id) AS parent_tbl, " +
"OBJECT_NAME(fk.referenced_object_id) AS ref_tbl, " +
"fk.delete_referential_action_desc AS del, " +
"fk.update_referential_action_desc AS upd " +
"FROM sys.foreign_keys fk ORDER BY fk.name";
try (Statement st = conn.createStatement(); ResultSet rs = st.executeQuery(sql)) {
while (rs.next()) {
Fk f = new Fk();
f.name = rs.getString("fk_name");
f.schema = rs.getString("sch");
f.parentTable = rs.getString("parent_tbl");
f.refTable = rs.getString("ref_tbl");
f.delAction = rs.getString("del");
f.updAction = rs.getString("upd");
fks.add(f);
}
}
String colSql =
"SELECT fk.name AS fk_name, " +
"COL_NAME(fkc.parent_object_id, fkc.parent_column_id) AS pc, " +
"COL_NAME(fkc.referenced_object_id, fkc.referenced_column_id) AS rc " +
"FROM sys.foreign_keys fk " +
"JOIN sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id " +
"ORDER BY fk.name, fkc.constraint_column_id";
try (Statement st = conn.createStatement(); ResultSet rs = st.executeQuery(colSql)) {
while (rs.next()) {
String n = rs.getString("fk_name");
for (Fk f : fks) {
if (f.name.equals(n)) {
f.cols.add(new String[]{rs.getString("pc"), rs.getString("rc")});
break;
}
}
}
}
// 1. Write restore script
String restorePath = "restore_fks.sql";
try (PrintWriter w = new PrintWriter(restorePath, StandardCharsets.UTF_8)) {
w.println("-- Restore script for G3HD (FMS-NEW) physical foreign keys");
w.println("-- Generated: " + new Timestamp(System.currentTimeMillis()));
w.println("USE [FMS-NEW];");
w.println("GO");
for (Fk f : fks) {
StringBuilder pcols = new StringBuilder(), rcols = new StringBuilder();
for (int i = 0; i < f.cols.size(); i++) {
if (i > 0) { pcols.append(", "); rcols.append(", "); }
pcols.append("[").append(f.cols.get(i)[0]).append("]");
rcols.append("[").append(f.cols.get(i)[1]).append("]");
}
w.printf("ALTER TABLE [%s].[%s] WITH CHECK ADD CONSTRAINT [%s] FOREIGN KEY(%s)%n",
f.schema, f.parentTable, f.name, pcols);
w.printf("REFERENCES [%s].[%s] (%s) ON DELETE %s ON UPDATE %s;%n",
f.schema, f.refTable, rcols, f.delAction, f.updAction);
w.println("GO");
}
w.println("-- End of restore script");
}
System.out.println("Restore script written to: " + restorePath + " (" + fks.size() + " FKs)");
// 2. Drop all FKs in one transaction
int dropped = 0;
for (Fk f : fks) {
String ddl = String.format("ALTER TABLE [%s].[%s] DROP CONSTRAINT [%s]",
f.schema, f.parentTable, f.name);
try (Statement st = conn.createStatement()) {
st.executeUpdate(ddl);
dropped++;
System.out.println("DROPPED: " + f.name + " (on " + f.parentTable + ")");
}
}
conn.commit();
System.out.println("\nCommitted. Dropped " + dropped + " foreign keys.");
// 3. Verify
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT COUNT(*) FROM sys.foreign_keys")) {
rs.next();
System.out.println("REMAINING FK COUNT = " + rs.getInt(1));
}
}
}
}