コード例 #1
0
ファイル: TestExportTo.cs プロジェクト: nofuture-git/31g
        internal static NoFuture.Sql.Mssql.Md.PsMetadata SerializedTableMetadata()
        {
            var psmd = new NoFuture.Sql.Mssql.Md.PsMetadata
            {
                IsComputedKeys = new List <string>(),
                TickKeys       = new List <string>
                {
                    "PersonType",
                    "Title",
                    "FirstName",
                    "MiddleName",
                    "LastName",
                    "Suffix",
                    "Demographics",
                    "rowguid",
                    "ModifiedDate"
                },
                PkKeys = new Dictionary <string, string> {
                    { "BusinessEntityID", "int" }
                },
                FkKeys = new Dictionary <string, string> {
                    { "BusinessEntityID", "int" }
                }
            };

            return(psmd);
        }
コード例 #2
0
ファイル: ExportTo.cs プロジェクト: nofuture-git/31g
        /// <summary>
        /// Will wrap the <see cref="val"/> in single-quotes if the <see cref="key"/> is found in 
        /// the <see cref="PsMetadata.TickKeys"/> list and the <see cref="val"/> does not equal the string
        /// "NULL" (case-insensitive).
        /// </summary>
        /// <param name="metaData"></param>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <param name="maxLength">
        /// Optional field to limit the size of string literals, set it to zero or less
        /// to not truncate any text from <see cref="val"/>
        /// </param>
        /// <returns></returns>
        public static string GetQryValueWrappedWithLimit(PsMetadata metaData, string key, string val, int maxLength)
        {
            if (string.IsNullOrWhiteSpace(key))
                return val;

            if (metaData == null)
                return val;

            if (metaData.AutoNumKeys.Any(x => string.Equals(x, key, Oic)) ||
                metaData.IsComputedKeys.Any(x => string.Equals(x, key, Oic)))
                return val;
            if (!metaData.TickKeys.Any(x => string.Equals(x, key, Oic)) || string.Equals(val, "NULL", Oic))
                return val;

            if (val.Contains("'"))
                val = val.Replace("'", "''");

            return val.Length > maxLength && maxLength > 0
                ? $"'{val.Substring(0, maxLength)}'"
                : $"'{val}'";
        }
コード例 #3
0
ファイル: ExportTo.cs プロジェクト: nofuture-git/31g
        /// <summary>
        /// Composes  SQL syntax as an insert, update or merge (based on the <see cref="stmtType"/>) statement given the various inputs.
        /// </summary>
        /// <param name="sqlStmt"></param>
        /// <param name="len"></param>
        /// <param name="stmtType"></param>
        /// <param name="metaData"></param>
        /// <param name="results"></param>
        /// <returns></returns>
        public static string ScriptDataBody(string sqlStmt, int len, ExportToStatementType stmtType, PsMetadata metaData,
            DataRow[] results)
        {
            if (results == null || results.Length <= 0)
                throw new ItsDeadJim("No records found.");

            //#get the table and schema names out of the expression
            var tempPsObj = GetTableSchemaAndNameFromExpression(sqlStmt);
            if (string.IsNullOrWhiteSpace(tempPsObj.TableName))
            {
                throw new RahRowRagee("The sql expression is either invalid or the 'from' statement " +
                                      "does not specify a fully qualified name ([catalog].[dbo].[tablename])");
            }
            var tableName = tempPsObj.TableName;
            var tableSchema = tempPsObj.SchemaName;
            List<string> colNames = null;

            var insertSyntax = new StringBuilder();
            var updateSyntax = new StringBuilder();

            var mergeDataLine = new List<string>();

            //#for each database record
            foreach (DataRow currec in results)
            {
                if(colNames == null)
                    colNames = currec.Table.Columns.OfType<DataColumn>().Select(x => x.ColumnName).ToList();

                var updateWhere = new List<string>();
                var setStmt = new List<string>();
                var insertStmt = new List<string>();
                var insertVals = new List<string>();
                var mergeVals = new List<string>();
                var counter = 0;
                foreach (var key in colNames)
                {
                    if (string.IsNullOrWhiteSpace(key))
                        continue;

                    if (metaData.AutoNumKeys.Any(x => string.Equals(x, key, Oic)) ||
                        metaData.IsComputedKeys.Any(x => string.Equals(x, key, Oic)))
                        continue;

                    //#eval out all 'DBNull.Value'
                    var val = string.IsNullOrWhiteSpace(currec[key].ToString()) ? "NULL" : currec[key].ToString();

                    //#truncate varcharesque values then wrap them in single quotes
                    val = GetQryValueWrappedWithLimit(metaData, key, val, len);
                    Tuple<string, string> formattedPair;

                    //#format both key and value with extra padding
                    if (stmtType == ExportToStatementType.UPDATE)
                    {
                        formattedPair = FormatKeyValue(key, val, len + 2, counter++);

                        var uws = $"{formattedPair.Item1} = {formattedPair.Item2}";

                        //#set a where statement off the primary key if that primary key was present in the select stmt
                        if (metaData.PkKeys.Keys.Any(x => string.Equals(x, key, Oic)))
                            updateWhere.Add(uws);
                        else
                            setStmt.Add(uws);
                    }

                    if (stmtType == ExportToStatementType.INSERT)
                    {
                        formattedPair =  FormatKeyValue(key, val, len + 2, counter++, true);

                        //#set the insert values neatly printed into text columns
                        insertStmt.Add($"{formattedPair.Item1}");
                        insertVals.Add($"{formattedPair.Item2}");
                    }

                    if (stmtType == ExportToStatementType.MERGE)
                    {
                        formattedPair = FormatKeyValue(key, val, len + 2, counter++, true);
                        mergeVals.Add(formattedPair.Item2);
                    }

                } //#end foreach datakey
                if (stmtType == ExportToStatementType.INSERT)
                {
                    //#close the blocks
                    insertSyntax.AppendFormat("\nINSERT INTO [{0}].[{1}]\n(\n\t", tableSchema, tableName);
                    insertSyntax.Append(string.Join(",\n\t", insertStmt));
                    insertSyntax.Append("\n)\nVALUES\n(\n\t");
                    insertSyntax.Append(string.Join(",\n\t", insertVals));
                    insertSyntax.Append("\n)\n");
                    continue;
                }
                if (stmtType == ExportToStatementType.UPDATE)
                {
                    updateSyntax.AppendFormat("\nUPDATE  [{0}].[{1}]\nSET     {2}\nWHERE   {3}\n", tableSchema, tableName,
                        string.Join(",\n        ", setStmt), string.Join(" AND ", updateWhere));
                }

                if (stmtType == ExportToStatementType.MERGE)
                {
                    mergeDataLine.Add($"({string.Join(",\n             ", mergeVals)})");
                }
            }

            if(stmtType == ExportToStatementType.INSERT || stmtType == ExportToStatementType.UPDATE)
                return stmtType == ExportToStatementType.INSERT ? insertSyntax.ToString() : updateSyntax.ToString();

            //draft the MERGE statement
            var mergeData = string.Join("\n    ,", mergeDataLine);
            var matchOnColumn = new List<string>();
            var otherColumn = new List<string>();

            //divide column names
            if (colNames == null)
                return null;

            foreach (var key in colNames)
            {
                if (string.IsNullOrWhiteSpace(key))
                    continue;

                if (metaData.AutoNumKeys.Any(x => string.Equals(x, key, Oic)) || metaData.IsComputedKeys.Any(x => string.Equals(x, key, Oic)))
                    continue;
                if (metaData.PkKeys.Keys.Any(x => string.Equals(x, key, Oic)))
                    matchOnColumn.Add($"[{key}]");
                else
                    otherColumn.Add($"[{key}]");
            }

            var matchOnList = matchOnColumn.Select(matchOn => string.Format("target.{0} = source.{0}", matchOn)).ToList();
            var updateSetList = otherColumn.Select(ot => string.Format("{0} = source.{0}", ot)).ToList();
            var insertNameList = metaData.IsIdentityInsert ? otherColumn : colNames;
            var insertValList = metaData.IsIdentityInsert
                ? otherColumn.Select(ot => $"source.{ot}").ToList()
                : colNames.Select(cn => $"source.{cn}").ToList();

            var mergeStatementBuilder = new StringBuilder();
            mergeStatementBuilder.AppendFormat("MERGE [{0}].[{1}] AS target\n", tableSchema, tableName);
            mergeStatementBuilder.Append("USING (\n");
            mergeStatementBuilder.Append("VALUES\n     ");
            mergeStatementBuilder.Append(mergeData);
            mergeStatementBuilder.AppendFormat("\n    ) AS source (\n             {0})\n", string.Join(",\n             ", colNames));
            mergeStatementBuilder.AppendFormat("ON ({0})\n", string.Join(" AND ", matchOnList));
            mergeStatementBuilder.AppendLine("WHEN MATCHED THEN");
            mergeStatementBuilder.AppendFormat("  UPDATE SET {0}\n", string.Join(",\n             ", updateSetList));
            mergeStatementBuilder.AppendLine("WHEN NOT MATCHED THEN");
            mergeStatementBuilder.AppendFormat("    INSERT ( {0}\n           )\n",
                string.Join(",\n             ", insertNameList));
            mergeStatementBuilder.AppendFormat("    VALUES ( {0}\n           );\n",
                string.Join(",\n             ", insertValList));

            return mergeStatementBuilder.ToString();
        }
コード例 #4
0
ファイル: TestExportTo.cs プロジェクト: nofuture-git/31g
        internal static NoFuture.Sql.Mssql.Md.PsMetadata SerializedTableMetadata()
        {
            var psmd = new NoFuture.Sql.Mssql.Md.PsMetadata
            {
                IsComputedKeys = new List<string>(),
                TickKeys = new List<string>
                {
                    "PersonType",
                    "Title",
                    "FirstName",
                    "MiddleName",
                    "LastName",
                    "Suffix",
                    "Demographics",
                    "rowguid",
                    "ModifiedDate"
                },
                PkKeys = new Dictionary<string, string> {{"BusinessEntityID", "int"}},
                FkKeys = new Dictionary<string, string> {{"BusinessEntityID", "int"}}
            };

            return psmd;
        }