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

如何无需手动解析从TSQL的CREATE TABLE脚本提取表属性信息?

无需手动解析的实现方案

你可以直接使用微软官方维护的Microsoft.SqlServer.TransactSql.ScriptDom库完成离线TSQL脚本解析,无需连接数据库,也不需要手动处理语法匹配。

使用步骤

  • 第一步:通过NuGet安装Microsoft.SqlServer.TransactSql.ScriptDom包,适配.NET Framework/.NET Core/.NET 5+全版本
  • 第二步:调用解析器解析CREATE TABLE脚本,示例代码如下:
using Microsoft.SqlServer.TransactSql.ScriptDom;
using System.Collections.Generic;
using System.IO;
using System.Linq;

public class TableParseResult
{
    public string TableName { get; set; }
    public List<TableAttribute> Attr { get; set; } = new();
}

public class TableAttribute
{
    public string ColumnName { get; set; }
    public string ColumnType { get; set; }
    public string Nullable { get; set; }
    public string Constraint { get; set; }
}

public static class SqlTableParser
{
    public static TableParseResult ParseCreateTableScript(string sqlScript)
    {
        var parser = new TSql160Parser(false);
        IList<ParseError> errors;
        var fragment = parser.Parse(new StringReader(sqlScript), out errors);
        
        if (errors != null && errors.Count > 0)
        {
            throw new InvalidDataException("SQL脚本格式错误");
        }

        var result = new TableParseResult();
        var createTableStmt = fragment.Batches
            .SelectMany(b => b.Statements)
            .OfType<CreateTableStatement>()
            .FirstOrDefault();
        
        if (createTableStmt == null) return result;

        // 提取表名
        result.TableName = createTableStmt.SchemaObjectName
            .Identifiers.LastOrDefault()?.Value ?? string.Empty;

        // 先提取所有字段定义
        var columnDefs = createTableStmt.Definition.ColumnDefinitions
            .ToDictionary(cd => cd.ColumnIdentifier.Value, cd => new TableAttribute
            {
                ColumnName = cd.ColumnIdentifier.Value,
                ColumnType = cd.DataType.ToSql(),
                Nullable = cd.IsNullable ? "NULL" : "NOT NULL"
            });

        // 处理约束
        foreach (var constraint in createTableStmt.Definition.TableConstraints)
        {
            if (constraint is UniqueConstraintDefinition pkConstraint && pkConstraint.IsPrimaryKey)
            {
                foreach (var col in pkConstraint.Columns)
                {
                    var colName = col.Column.MultiPartIdentifier.Identifiers.Last().Value;
                    if (columnDefs.ContainsKey(colName))
                    {
                        columnDefs[colName].Constraint = "PK";
                    }
                }
            }
            // 可自行扩展外键、唯一约束等其他类型的解析逻辑
        }

        result.Attr = columnDefs.Values.ToList();
        return result;
    }

    // 辅助方法把DataType节点转成字符串
    private static string ToSql(this DataType dataType)
    {
        if (dataType is SqlDataType sqlDataType)
        {
            var typeName = sqlDataType.SqlDataTypeOption.ToString();
            if (sqlDataType.Parameters.Any())
            {
                return $"{typeName}({string.Join(",", sqlDataType.Parameters.Select(p => p.Value))})";
            }
            return typeName;
        }
        return dataType.ToString();
    }
}
  • 第三步:调用方法即可得到你需要的结果,调用示例:
string sql = @"CREATE TABLE [dbo].[person]
(
    [id] [int] NOT NULL ,
    [Name] [VARCHAR](1) NULL,
    [fk] [int] NULL,
    CONSTRAINT [PK_person] 
        PRIMARY KEY CLUSTERED ([id])
)";

var ParseResult = SqlTableParser.ParseCreateTableScript(sql);
string tblName = ParseResult.TableName; // 输出person
TableAttribute a0 = ParseResult.Attr[0]; // 对应{"id", "int", "NOT NULL", "PK"}
TableAttribute a1 = ParseResult.Attr[1]; // 对应{"Name", "VARCHAR(1)", "NULL", null}
TableAttribute a2 = ParseResult.Attr[2]; // 对应{"fk", "int", "NULL", null}

扩展说明

你可以根据自己的需求扩展约束解析逻辑,支持外键、唯一键、默认值等所有CREATE TABLE支持的约束类型,不需要修改底层解析逻辑,只需补充对应约束类型的处理分支即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 19:36:00