You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从动态TSQL语句中获取列名及原始值的技术求助

Got it, let's figure out how to extract both column names and their corresponding raw values from dynamic SQL statements—since you mentioned your current setup only pulls column names, here are practical, actionable solutions tailored to different scenarios:

1. Use a SQL Parser (Cross-Language, Universal Approach)

The most reliable way is to parse the dynamic SQL into an Abstract Syntax Tree (AST), then traverse the tree to map columns to their raw values. This works for any dynamically generated SQL, whether it's hardcoded strings or user-generated queries.

Example with Java (JSqlParser)

JSqlParser is a robust library for parsing SQL across dialects:

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.update.Update;

public class SqlColumnValueExtractor {
    public static void parseInsertSql(String sql) throws JSQLParserException {
        Insert insertStmt = (Insert) CCJSqlParserUtil.parse(sql);
        // Get column names
        System.out.println("Columns: " + insertStmt.getColumns());
        // Get raw literal values (handles strings, numbers, NULL, etc.)
        System.out.println("Raw Values: " + insertStmt.getItemsList());
    }

    public static void parseUpdateSql(String sql) throws JSQLParserException {
        Update updateStmt = (Update) CCJSqlParserUtil.parse(sql);
        updateStmt.getSets().forEach(setItem -> {
            System.out.println("Column: " + setItem.getColumn());
            System.out.println("Raw Value: " + setItem.getValue());
        });
    }

    public static void main(String[] args) throws JSQLParserException {
        String dynamicInsert = "INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com')";
        parseInsertSql(dynamicInsert);

        String dynamicUpdate = "UPDATE users SET name = 'Bob', email = 'bob@example.com' WHERE id = 1";
        parseUpdateSql(dynamicUpdate);
    }
}

Example with Python (sqlparse)

sqlparse is a lightweight, easy-to-use parser for Python:

import sqlparse
from sqlparse.sql import IdentifierList

def extract_insert_details(sql):
    parsed = sqlparse.parse(sql)[0]
    # Extract columns
    columns = next(t for t in parsed.tokens if isinstance(t, IdentifierList))
    column_names = [col.value.strip() for col in columns.get_identifiers()]
    # Extract raw values
    values_clause = next(t for t in parsed.tokens if t.value.upper() == 'VALUES')
    values = next(t for t in values_clause.parent.tokens if isinstance(t, IdentifierList))
    raw_values = [val.value.strip() for val in values.get_identifiers()]
    print(f"Columns: {column_names}\nRaw Values: {raw_values}")

def extract_update_details(sql):
    parsed = sqlparse.parse(sql)[0]
    set_clause = next(t for t in parsed.tokens if t.value.upper() == 'SET')
    set_items = next(t for t in set_clause.parent.tokens if isinstance(t, IdentifierList))
    for item in set_items.get_identifiers():
        if '=' in item.value:
            col, val = item.value.split('=', 1)
            print(f"Column: {col.strip()}, Raw Value: {val.strip()}")

# Test with sample dynamic SQL
extract_insert_details("INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com')")
extract_update_details("UPDATE users SET name = 'Bob', email = 'bob@example.com' WHERE id = 1")

2. Track Values During SQL Construction (Application-Level Win)

If you're generating the dynamic SQL in your own code, you don't need to parse it at all—just track columns and values as you build the query. This is simpler and avoids parsing overhead.

Example with Java

import java.util.HashMap;
import java.util.Map;

public class DynamicSqlBuilder {
    public static void main(String[] args) {
        // Track columns and values in a map while building the SQL
        Map<String, Object> columnValueMap = new HashMap<>();
        columnValueMap.put("id", 1);
        columnValueMap.put("name", "Alice");
        columnValueMap.put("email", "alice@example.com");

        // Build the SQL string from the map
        String columns = String.join(", ", columnValueMap.keySet());
        String placeholders = String.join(", ", java.util.Collections.nCopies(columnValueMap.size(), "?"));
        String sql = String.format("INSERT INTO users (%s) VALUES (%s)", columns, placeholders);

        // Now you have direct access to both columns and raw values
        System.out.println("Columns: " + columnValueMap.keySet());
        System.out.println("Raw Values: " + columnValueMap.values());
        System.out.println("Generated SQL: " + sql);
    }
}

3. Handle Prepared Statements with Parameter Binding

If you're using prepared statements (e.g., Java's PreparedStatement, Python's psycopg2), the SQL only contains placeholders. In this case, track the parameter values separately as you bind them—they'll map directly to the columns you defined.

Example with Python (psycopg2)

import psycopg2

# Connect to your database
conn = psycopg2.connect("dbname=my_db user=postgres")
cur = conn.cursor()

# Define columns and their raw values explicitly
columns = ["id", "name", "email"]
raw_values = (1, "Alice", "alice@example.com")

# Build prepared statement SQL
sql = f"INSERT INTO users ({', '.join(columns)}) VALUES ({', '.join(['%s']*len(columns))})"
cur.execute(sql, raw_values)

# You already have columns and values from your variables
print(f"Columns: {columns}\nRaw Values: {raw_values}")

conn.commit()
cur.close()
conn.close()

Key Notes to Keep in Mind

  • Expression Values: If your SQL uses expressions (e.g., NOW(), COUNT(*) instead of literal values), parsers will return the expression string as the "raw value"—adjust your logic if you need to distinguish literals from expressions.
  • SQL Dialects: Most parsers support multiple dialects (MySQL, PostgreSQL, etc.)—make sure to configure the parser for your database type if needed.
  • Security: If parsing user-generated SQL, avoid executing any parsed content directly to prevent SQL injection risks.

内容的提问来源于stack exchange,提问作者Jigar Parekh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:49:54