Пример #1
0
        string createRowStatement(int rowNo, List <string> keys, Vars sv, string tableName, bool firstInBatch, SqlUpdateMode updateMode, DatabaseType dbType)
        {
            StringBuilder sbInsert = new StringBuilder();

            if (updateMode == SqlUpdateMode.Merge)
            {
                appendSelect(sbInsert, rowNo, keys, sv, firstInBatch, dbType);
                return(sbInsert.ToString());
            }
            if (InsertSyntax == SqlInsertSyntax.Select)
            {
                if (firstInBatch || UpdateMode != SqlUpdateMode.None)
                {
                    sbInsert.Append("INSERT INTO ");
                    sbInsert.Append(tableName);
                    sbInsert.Append(" ( ");
                    appendColumns(sbInsert, keys, dbType);
                    sbInsert.Append(" )");
                    sbInsert.AppendLine();
                }
                appendSelect(sbInsert, rowNo, keys, sv, firstInBatch || UpdateMode != SqlUpdateMode.None, dbType);
            }
            else
            {
                sbInsert.Append("INSERT INTO ");
                sbInsert.Append(tableName);
                sbInsert.Append(" ( ");
                appendColumns(sbInsert, sv.Keys, dbType);
                sbInsert.AppendLine(" )");
                sbInsert.Append("VALUES (");
                bool ff = true;
                foreach (var v in sv.Values)
                {
                    if (!ff)
                    {
                        sbInsert.Append(",");
                    }
                    ff = false;
                    sbInsert.Append(SqlUtil.GetQuotedValue(dbType, v, NoQuotePrefix, Translate));
                }
                sbInsert.AppendLine(")");
            }

            if (updateMode == SqlUpdateMode.None)
            {
                return(sbInsert.ToString());
            }

            var updateKeys = (Context.TransformStr(Keys, Transform) ?? string.Empty);

            if (string.IsNullOrEmpty(updateKeys))
            {
                throw new ParsingException("Key columns must be specified in order to enable updates");
            }
            string[] kfield = updateKeys.Split(';', ',');

            StringBuilder             sList = new StringBuilder();
            StringBuilder             sCond = new StringBuilder();
            StringBuilder             sUpd  = new StringBuilder();
            Dictionary <string, bool> k     = new Dictionary <string, bool>(StringComparer.InvariantCultureIgnoreCase);

            for (int i = 0; i < kfield.Length; ++i)
            {
                string kf = kfield[i].Trim();
                kfield[i] = kf;
                if (sList.Length != 0)
                {
                    sList.Append(", ");
                }
                sList.Append(SqlUtil.SqlName(dbType, kf));
                if (sCond.Length != 0)
                {
                    sCond.Append(" AND ");
                }
                sCond.Append("(");
                sCond.Append(SqlUtil.SqlName(dbType, kf));
                sCond.Append(" = ");
                sCond.Append(SqlUtil.GetQuotedValue(dbType, sv[kf], NoQuotePrefix, Translate));
                sCond.Append(")");
                k[kf] = true;
            }
            // Prepare update statement
            sUpd.AppendFormat("UPDATE " + tableName);
            sUpd.AppendLine();
            sUpd.Append("SET ");
            bool first = true;

            foreach (var v in sv)
            {
                if (!k.ContainsKey(v.Name))
                {
                    if (!first)
                    {
                        sUpd.Append(", ");
                    }
                    first = false;
                    sUpd.Append(SqlUtil.SqlName(dbType, v.Name));
                    sUpd.Append("=");
                    sUpd.Append(SqlUtil.GetQuotedValue(dbType, v.Value, NoQuotePrefix, Translate));
                }
            }
            sUpd.AppendLine();
            var kfieldCond = sCond.ToString();

            sUpd.AppendLine("WHERE " + kfieldCond);

            StringBuilder sb = new StringBuilder();

            if (updateMode == SqlUpdateMode.MsSql)
            {
                sb.Append(sUpd.ToString());
                sb.AppendLine("IF @@ROWCOUNT=0");
            }
            else
            {
                sb.AppendFormat("IF EXISTS(SELECT {0} FROM {1} WHERE {2})", sList.ToString(), tableName, kfieldCond);
                sb.AppendLine();
                sb.Append(sUpd.ToString());
                sb.AppendLine("ELSE");
            }
            sb.AppendLine(sbInsert.ToString());
            sb.AppendLine();
            return(sb.ToString());
        }
Пример #2
0
        private void prepareHeaderAndFooter(StringBuilder batch, StringBuilder footer, string tableName, List <string> keys, SqlUpdateMode updateMode, DatabaseType dbType)
        {
            if (IdentityInsert)
            {
                batch.Append("SET IDENTITY_INSERT " + tableName + " ON\n");
                footer.AppendLine("SET IDENTITY_INSERT " + tableName + " OFF\n");
            }
            if (updateMode == SqlUpdateMode.Merge)
            {
                string[] sqlKeys = new string[keys.Count];
                for (int i = 0; i < keys.Count; ++i)
                {
                    sqlKeys[i] = SqlUtil.SqlName(dbType, keys[i]);
                }

                batch.AppendLine("MERGE " + tableName + " AS DST");
                batch.AppendLine("USING (");
                footer.AppendLine(") AS SRC(" + string.Join(", ", sqlKeys) + ")");
                footer.Append("    ON ");

                var updateKeys = (Context.TransformStr(Keys, Transform) ?? string.Empty);
                if (string.IsNullOrEmpty(updateKeys))
                {
                    throw new ParsingException("Key columns must be specified in order to enable updates");
                }
                string[] kfield = updateKeys.Split(';', ',');
                for (int i = 0; i < kfield.Length; ++i)
                {
                    kfield[i] = SqlUtil.SqlName(dbType, kfield[i].Trim());
                }

                Dictionary <string, bool> kk = new Dictionary <string, bool>(StringComparer.InvariantCultureIgnoreCase);
                for (int i = 0; i < kfield.Length; ++i)
                {
                    if (i != 0)
                    {
                        footer.Append(" AND ");
                    }
                    footer.AppendFormat("DST.{0}=SRC.{0}", kfield[i]);
                    kk[kfield[i]] = true;
                }
                footer.AppendLine();
                footer.AppendLine("WHEN MATCHED THEN");
                footer.Append("    UPDATE SET ");
                bool ff = true;

                for (int i = 0; i < sqlKeys.Length; ++i)
                {
                    if (kk.ContainsKey(sqlKeys[i]))
                    {
                        continue;
                    }
                    if (!ff)
                    {
                        footer.Append(",");
                    }
                    ff = false;
                    footer.AppendFormat("{0} = SRC.{0}", sqlKeys[i]);
                }
                footer.AppendLine();
                footer.AppendLine("WHEN NOT MATCHED THEN");
                footer.Append("    INSERT (");
                for (int i = 0; i < sqlKeys.Length; ++i)
                {
                    if (i != 0)
                    {
                        footer.Append(",");
                    }
                    footer.Append(sqlKeys[i]);
                }
                footer.AppendLine(" )");
                footer.Append("    VALUES (");
                for (int i = 0; i < sqlKeys.Length; ++i)
                {
                    if (i != 0)
                    {
                        footer.Append(",");
                    }
                    footer.Append("SRC." + sqlKeys[i]);
                }
                footer.AppendLine(");");
            }
        }
Пример #3
0
        private void prepareHeaderAndFooter(StringBuilder batch, StringBuilder footer, string tableName, List<string> keys, SqlUpdateMode updateMode, DatabaseType dbType)
        {
            if (IdentityInsert)
            {
                batch.Append("SET IDENTITY_INSERT " + tableName + " ON\n");
                footer.AppendLine("SET IDENTITY_INSERT " + tableName + " OFF\n");
            }
            if (updateMode==SqlUpdateMode.Merge)
            {
                string[] sqlKeys = new string[keys.Count];
                for (int i = 0; i < keys.Count; ++i)
                    sqlKeys[i] = SqlUtil.SqlName(dbType, keys[i]);

                batch.AppendLine("MERGE " + tableName + " AS DST");
                batch.AppendLine("USING (");
                footer.AppendLine(") AS SRC("+string.Join(", ",sqlKeys)+")");
                footer.Append("    ON ");

                var updateKeys = (Context.TransformStr(Keys, Transform) ?? string.Empty);
                if (string.IsNullOrEmpty(updateKeys))
                    throw new ParsingException("Key columns must be specified in order to enable updates");
                string[] kfield = updateKeys.Split(';', ',');
                for (int i = 0; i < kfield.Length; ++i)
                    kfield[i] = SqlUtil.SqlName(dbType, kfield[i].Trim());

                Dictionary<string,bool> kk=new Dictionary<string, bool>(StringComparer.InvariantCultureIgnoreCase);
                for (int i = 0; i < kfield.Length; ++i)
                {
                    if (i != 0)
                        footer.Append(" AND ");
                    footer.AppendFormat("DST.{0}=SRC.{0}", kfield[i]);
                    kk[kfield[i]] = true;
                }
                footer.AppendLine();
                footer.AppendLine("WHEN MATCHED THEN");
                footer.Append("    UPDATE SET ");
                bool ff = true;

                for (int i = 0; i < sqlKeys.Length; ++i)
                {
                    if (kk.ContainsKey(sqlKeys[i]))
                        continue;
                    if (!ff)
                        footer.Append(",");
                    ff = false;
                    footer.AppendFormat("{0} = SRC.{0}",sqlKeys[i]);
                }
                footer.AppendLine();
                footer.AppendLine("WHEN NOT MATCHED THEN");
                footer.Append("    INSERT (");
                for (int i = 0; i < sqlKeys.Length; ++i)
                {
                    if (i != 0)
                        footer.Append(",");
                    footer.Append(sqlKeys[i]);
                }
                footer.AppendLine(" )");
                footer.Append("    VALUES (");
                for (int i = 0; i < sqlKeys.Length; ++i)
                {
                    if (i != 0)
                        footer.Append(",");
                    footer.Append("SRC."+sqlKeys[i]);
                }
                footer.AppendLine(");");
            }
        }
Пример #4
0
        /// Execute action
        public override object Execute()
        {
            object o = base.Execute();

            if (o != null)
            {
                return(0);
            }

            if (Database.Current == null)
            {
                throw new ScriptRuntimeException("Database is not specified");
            }
            var    dbType      = Database.Current.SpecificDatabaseType;
            string tableName   = SqlUtil.SqlName(dbType, Context.TransformStr(Table, Transform));
            string firstHeader = string.Empty;

            if (Truncate)
            {
                firstHeader = "TRUNCATE TABLE " + tableName + Environment.NewLine;
            }

            SqlUpdateMode upMode = UpdateMode;

            if (upMode == SqlUpdateMode.Auto)
            {
                if (dbType == DatabaseType.MsSql2008)
                {
                    upMode = SqlUpdateMode.Merge;
                }
                else if ((dbType & DatabaseType.MsSql) == DatabaseType.MsSql)
                {
                    upMode = SqlUpdateMode.MsSql;
                }
                else
                {
                    upMode = SqlUpdateMode.Simple;
                }
            }

            StringBuilder sbFooter = new StringBuilder();

            StringBuilder batch = new StringBuilder();
            List <string> keys  = new List <string>();

            int rowsInBatch   = 0;
            int prevColsCount = -1;
            int maxBatch      = MaxBatch;

            if (maxBatch < 1)
            {
                maxBatch = 1;
            }
            if ((dbType & DatabaseType.MsSql) != DatabaseType.MsSql && InsertSyntax == SqlInsertSyntax.Values)
            {
                maxBatch = 1;
            }
            int           rowNo = 0;
            StringBuilder sbO   = new StringBuilder();

            foreach (Vars sv in GetData())
            {
                Context.CheckAbort();
flush:
                if (sv.Count != prevColsCount && batch.Length != 0)
                {
                    if (string.IsNullOrEmpty(SqlTo))
                    {
                        runCommand(firstHeader + batch + sbFooter);
                    }
                    else
                    {
                        sbO.AppendLine(firstHeader + batch + sbFooter);
                    }

                    batch.Length = 0;
                    firstHeader  = string.Empty;
                    rowsInBatch  = 0;
                }

                if (rowsInBatch == 0)
                {
                    keys.Clear();
                    foreach (Var c in sv)
                    {
                        keys.Add(c.Name);
                    }
                    prevColsCount   = sv.Count;
                    sbFooter.Length = 0;
                    prepareHeaderAndFooter(batch, sbFooter, tableName, keys, upMode, dbType);
                }

                string cr = createRowStatement(rowNo, keys, sv, tableName, rowsInBatch == 0, upMode, dbType);
                if (rowsInBatch >= 1 && (cr.Length + firstHeader.Length + batch.Length + sbFooter.Length > MaxLength || rowsInBatch >= maxBatch))
                {
                    // If we append this command to the batch, it will be too long.
                    prevColsCount = -1;
                    goto flush;
                }
                batch.Append(cr);
                rowsInBatch++;
            }
            if (batch.Length != 0)
            {
                if (string.IsNullOrEmpty(SqlTo))
                {
                    runCommand(firstHeader + batch + sbFooter);
                }
                else
                {
                    sbO.AppendLine(firstHeader + batch + sbFooter);
                }
            }
            if (!string.IsNullOrEmpty(SqlTo))
            {
                Context.OutTo(Context.TransformStr(SqlTo, Transform), sbO.ToString());
            }

            return(null);
        }
Пример #5
0
        string createRowStatement(int rowNo,List<string> keys, Vars sv, string tableName, bool firstInBatch, SqlUpdateMode updateMode, DatabaseType dbType)
        {
            StringBuilder sbInsert = new StringBuilder();
            if (updateMode == SqlUpdateMode.Merge)
            {
                appendSelect(sbInsert, rowNo, keys, sv, firstInBatch, dbType);
                return sbInsert.ToString();
            }
            if (InsertSyntax == SqlInsertSyntax.Select)
            {
                if (firstInBatch || UpdateMode != SqlUpdateMode.None)
                {
                    sbInsert.Append("INSERT INTO ");
                    sbInsert.Append(tableName);
                    sbInsert.Append(" ( ");
                    appendColumns(sbInsert, keys, dbType);
                    sbInsert.Append(" )");
                    sbInsert.AppendLine();
                }
                appendSelect(sbInsert, rowNo, keys, sv, firstInBatch || UpdateMode != SqlUpdateMode.None, dbType);
            }
            else
            {
                sbInsert.Append("INSERT INTO ");
                sbInsert.Append(tableName);
                sbInsert.Append(" ( ");
                appendColumns(sbInsert, sv.Keys, dbType);
                sbInsert.AppendLine(" )");
                sbInsert.Append("VALUES (");
                bool ff = true;
                foreach (var v in sv.Values)
                {
                    if (!ff)
                        sbInsert.Append(",");
                    ff = false;
                    sbInsert.Append(SqlUtil.GetQuotedValue(dbType, v, NoQuotePrefix, Translate));
                }
                sbInsert.AppendLine(")");
            }

            if (updateMode == SqlUpdateMode.None)
                return sbInsert.ToString();

            var updateKeys = (Context.TransformStr(Keys, Transform) ?? string.Empty);
            if (string.IsNullOrEmpty(updateKeys))
                throw new ParsingException("Key columns must be specified in order to enable updates");
            string[] kfield = updateKeys.Split(';', ',');

            StringBuilder sList = new StringBuilder();
            StringBuilder sCond = new StringBuilder();
            StringBuilder sUpd = new StringBuilder();
            Dictionary<string,bool> k=new Dictionary<string, bool>(StringComparer.InvariantCultureIgnoreCase);
            for (int i=0;i<kfield.Length;++i)
            {
                string kf = kfield[i].Trim();
                kfield[i] = kf;
                if (sList.Length!=0)
                    sList.Append(", ");
                sList.Append(SqlUtil.SqlName(dbType, kf));
                if (sCond.Length!=0)
                    sCond.Append(" AND ");
                sCond.Append("(");
                sCond.Append(SqlUtil.SqlName(dbType, kf));
                sCond.Append(" = ");
                sCond.Append(SqlUtil.GetQuotedValue(dbType, sv[kf], NoQuotePrefix, Translate));
                sCond.Append(")");
                k[kf] = true;
            }
            // Prepare update statement
            sUpd.AppendFormat("UPDATE " + tableName);
            sUpd.AppendLine();
            sUpd.Append("SET ");
            bool first = true;
            foreach (var v in sv)
                if (!k.ContainsKey(v.Name))
                {
                    if (!first)
                        sUpd.Append(", ");
                    first = false;
                    sUpd.Append(SqlUtil.SqlName(dbType, v.Name));
                    sUpd.Append("=");
                    sUpd.Append(SqlUtil.GetQuotedValue(dbType, v.Value, NoQuotePrefix, Translate));
                }
            sUpd.AppendLine();
            var kfieldCond = sCond.ToString();
            sUpd.AppendLine("WHERE "+kfieldCond);

            StringBuilder sb=new StringBuilder();
            if (updateMode == SqlUpdateMode.MsSql)
            {
                sb.Append(sUpd.ToString());
                sb.AppendLine("IF @@ROWCOUNT=0");
            }
            else
            {
                sb.AppendFormat("IF EXISTS(SELECT {0} FROM {1} WHERE {2})", sList.ToString(), tableName, kfieldCond);
                sb.AppendLine();
                sb.Append(sUpd.ToString());
                sb.AppendLine("ELSE");
            }
            sb.AppendLine(sbInsert.ToString());
            sb.AppendLine();
            return sb.ToString();
        }