コード例 #1
0
 public static DataTable ParseTableCreate(string statement)
 {
     try
     {
         List <string> warningMessages = new List <string>();
         // Get first create statement
         Match createRegexMatch = Regex.Match(statement, @"(?i)create[^;]+;");
         if (!createRegexMatch.Success)
         {
             throw new Exception("Unable to parse create statement.");
         }
         // Get create statement parts
         Match tableCreateRegexMatch = Regex.Match(createRegexMatch.Value, @"(?i)create[\s]+table[\s]+(?<TableSchema>[^.]+).(?<TableName>[^\s]+)\s*\((?<ColumnDefinitions>(?:.|\s)+)\);");
         if (!tableCreateRegexMatch.Success)
         {
             throw new SqlScriptParsingException("Unable to parse table create statement.");
         }
         // Get table schema
         Group matchSearch = tableCreateRegexMatch.Groups["TableSchema"];
         if (!matchSearch.Success)
         {
             throw new SqlScriptParsingException("Unable to parse table create statement - TableSchema.");
         }
         string tableSchema = matchSearch.Value;
         tableSchema = tableSchema.Replace("[", "").Replace("]", "");
         // Get table name
         matchSearch = tableCreateRegexMatch.Groups["TableName"];
         if (!matchSearch.Success)
         {
             throw new SqlScriptParsingException("Unable to parse table create statement - TableName.");
         }
         string tableName = matchSearch.Value;
         tableName = tableName.Replace("[", "").Replace("]", "");
         // Get field definitions
         matchSearch = tableCreateRegexMatch.Groups["ColumnDefinitions"];
         if (!matchSearch.Success)
         {
             throw new SqlScriptParsingException("Unable to parse table create statement - ColumnDefinitions.");
         }
         string columnDefinitionsReplaceNewLine = matchSearch.Value.Replace("\r\n", "\n");
         // Get individual column definitions
         //MatchCollection columnDefinitionRegexMatch = Regex.Matches(matchSearch.Value, @"(?i)(?:(?<ColumnDefinition>[\s]*(?<ColumnName>[\S]+)[\s]+(?<DataType>[a-z2_]+)[\s]*(?<Precision>\((?:max|[0-9]+|[0-9]+,[\s]+[0-9])\))?[\s]+(?<Nullability>null|not[\s]null)?,?(?<ColumnConstraint>primary[\s]key|unique)?,?)|(?<ColumnConstraintDefinition>[\s]*constraint[\s]+[\S]+[\s]+(?:(?:(?:primary[\s]+key|unique|)[\s]+(?:clustered|non[\s]clustered)[\s]*(?:\([^\)]+\))?)|(?:foreign[\s]+key[\s]+[\S]+[\s]+references[\s]+[\S]+[\s]+\([^\)]+\))),?))");
         //MatchCollection columnDefinitionRegexMatch = Regex.Matches(matchSearch.Value, @"(?i)(?:(?<ColumnDefinition>[\s]*(?<ColumnName>(?!constraint)[\S]+)[\s]+(?<DataType>[\[a-z2_\]]+)[\s]*(?<Precision>\((?:max|[0-9]+|[0-9]+,[\s]+[0-9])\))?[\s]+(?<Nullability>null|not[\s]null)?,?(?<ColumnConstraint>primary[\s]key|unique)?,?)|(?<ColumnConstraintDefinition>[\s]*constraint[\s]+(?<ConstraintName>[\S]+)[\s]+(?:(?:(?:(?<ConstraintType>primary[\s]+key)|unique|)[\s]+(?:clustered|non[\s]clustered)[\s]*(?:\((?<ConstraintColumnNames>[^\)]+)\))?)|(?:foreign[\s]+key[\s]+[\S]+[\s]+references[\s]+[\S]+[\s]+\([^\)]+\))),?))");
         //MatchCollection columnDefinitionRegexMatch = Regex.Matches(matchSearch.Value, @"(?i)(?:(?<ColumnDefinition>\[?(?<ColumnName>(?!constraint)[^\s,\]]+)\]?[\s]+(?:\[?(?<ColumnDataType>[a-z2_]+)\]?)[\s]*(?:\((?<ColumnDataTypePrecision>(?:max|[0-9]+|[0-9]+,[\s]+[0-9]))\))?[\s]+(?<ColumnConstraint>(?:constraint[\s]+[\S]+[\s]+(?:default[\s]+[\S]+)?))?[\s]*(?<ColumnIdentity>identity[\s]*(?:\([0-9]+,[\s]*[0-9]+\))?)?[\s]*(?<ColumnNotForReplication>not[\s]+for[\s]+replication)?[\s]*(?<ColumnNullability>null|not[\s]null)?,?(?<TableConstraint>primary[\s]key|unique)?,?)|(?<TableConstraintDefinition>constraint[\s]+\[?(?<TableConstraintName>[^\s\]]+)\]?[\s]+(?:(?<TableConstraintUnique>(?<TableConstraintUniqueType>primary[\s]+key|unique)[\s]+(?:clustered|non[\s]clustered)[\s]*(?:\((?<TableConstraintColumnNames>[^\)]+)\))?)|(?<TableConstraintForeignKey>foreign[\s]+key[\s]+[\S]+[\s]+references[\s]+[\S]+[\s]+\([^\)]+\))),?))");
         MatchCollection columnDefinitionRegexMatch = Regex.Matches(columnDefinitionsReplaceNewLine, @"(?im)(?:(?<TableConstraintDefinition>^\s*(?:constraint\s+\[?(?<TableConstraintName>[^\s\]]+)\]?\s+)?(?:(?<TableConstraintUnique>(?<TableConstraintUniqueType>primary\s+key|unique)\s+(?:clustered|non\s*clustered)\s*(?:\((?<TableConstraintColumnNames>[^\)]+)\))?)|(?<TableConstraintForeignKey>foreign[\s]+key[\s]+[\S]+[\s]+references[\s]+[\S]+[\s]+\([^\)]+\))),?)|(?<ColumnDefinition>^\s*\[?(?<ColumnName>(?!constraint)[^\s,\]]+)\]?[\s]+(?:\[?(?<ColumnDataType>[a-z2_]+)\]?)[\s]*(?:\((?<ColumnDataTypePrecision>(?:max|[0-9]+|[0-9]+,[\s]+[0-9]))\))?[\s]+(?<ColumnConstraint>(?:constraint[\s]+[\S]+[\s]+(?:default[\s]+[\S]+)?))?[\s]*(?<ColumnIdentity>identity[\s]*(?:\([0-9]+,[\s]*[0-9]+\))?)?[\s]*(?<ColumnNotForReplication>not[\s]+for[\s]+replication)?[\s]*(?<ColumnNullability>null|not[\s]null)?,?\s*$(?<TableConstraint>primary[\s]key|unique)?,?))");
         if (columnDefinitionRegexMatch.Count < 0)
         {
             throw new SqlScriptParsingException("Unable to parse table create statement - individual column definitions.");
         }
         DataTable  dataTable = new DataTable($"{tableSchema}.{tableName}");
         DataColumn dataColumn;
         // Iterate through individual column definitions and create new data column objects
         foreach (Match definition in columnDefinitionRegexMatch)
         {
             // Check whether definition is table constraint
             if (definition.Groups["TableConstraintDefinition"].Success)
             {
                 // Check if primary key
                 matchSearch = definition.Groups["TableConstraintUniqueType"];
                 if (matchSearch.Success && matchSearch.Value.ToLower().Contains("primary"))
                 {
                     matchSearch = definition.Groups["TableConstraintColumnNames"];
                     if (matchSearch.Success)
                     {
                         List <DataColumn> primaryKeyColumns = new List <DataColumn>();
                         MatchCollection   primaryKeyColumnNameMatchCollection = Regex.Matches(matchSearch.Value, @"(?i)\[?(?<PrimaryKeyColumnName>[^\s\]]+)\]?[\s]+(?:asc|desc)");
                         foreach (Match primaryKeyColumnNameMatch in primaryKeyColumnNameMatchCollection)
                         {
                             // Get primary key column name
                             matchSearch = primaryKeyColumnNameMatch.Groups["PrimaryKeyColumnName"];
                             if (!matchSearch.Success)
                             {
                                 throw new SqlScriptParsingException("Unable to parse table primary key - ColumnName.");
                             }
                             string primaryKeyColumnName = matchSearch.Value;
                             primaryKeyColumns.Add(dataTable.Columns[primaryKeyColumnName]);
                         }
                         dataTable.PrimaryKey = primaryKeyColumns.ToArray();
                     }
                 }
             }
             else
             {
                 // Get column name
                 matchSearch = definition.Groups["ColumnName"];
                 if (!matchSearch.Success)
                 {
                     throw new SqlScriptParsingException("Unable to parse table create statement - individual column definitions - ColumnName.");
                 }
                 string columnName = matchSearch.Value;
                 // Get data type
                 matchSearch = definition.Groups["ColumnDataType"];
                 if (!matchSearch.Success)
                 {
                     throw new SqlScriptParsingException("Unable to parse table create statement - individual column definitions - DataType.");
                 }
                 string dataType = matchSearch.Value;
                 // Get precision
                 string precision = string.Empty;
                 matchSearch = definition.Groups["ColumnDataTypePrecision"];
                 if (matchSearch.Success)
                 {
                     precision = matchSearch.Value;
                     precision = precision.Replace("(", "").Replace(")", "");
                 }
                 else
                 {
                     warningMessages.Add($"Column definition parsing warning - Could not determine Precision for: \"{definition.Value}\".");
                 }
                 // Get nullability
                 string nullability = string.Empty;
                 matchSearch = definition.Groups["ColumnNullability"];
                 if (matchSearch.Success)
                 {
                     nullability = matchSearch.Value;
                 }
                 else
                 {
                     warningMessages.Add($"Could not determine - Nullability.");
                 }
                 Type nativeDataType = SqlStatementParser.SqlDbEngineTypeToNativeType(dataType);
                 // Create new data column
                 dataColumn = new DataColumn(columnName, nativeDataType);
                 dataColumn.ExtendedProperties.Add("SqlDbEngineType", $"{dataType}{(string.IsNullOrWhiteSpace(precision) ? string.Empty : $"({precision})")}");
                 if (nativeDataType == typeof(string) && precision.ToLower() != "max")
                 {
                     dataColumn.MaxLength = int.Parse(precision);
                 }
                 dataColumn.AllowDBNull = string.IsNullOrWhiteSpace(nullability) || nullability.ToLower() == "null";
                 dataTable.Columns.Add(dataColumn);
             }
         }
         return(dataTable);
     }