using FreeSql.Internal; using System; using System.Collections.Generic; using System.Data; using System.Text; using System.Threading.Tasks; namespace FreeSql.Odbc.SqlServer { class OdbcSqlServerInsert : Internal.CommonProvider.InsertProvider where T1 : class { public OdbcSqlServerInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); public override string ToSql() { var versionGreaterThan10 = (_commonUtils as OdbcSqlServerUtils).ServerVersion > 10; return this.ToSqlValuesOrSelectUnionAll(versionGreaterThan10); } protected override long RawExecuteIdentity() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try { long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { exception = ex; throw ex; } finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } protected override List RawExecuteInserted() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var sb = new StringBuilder(); sb.Append(" OUTPUT "); var colidx = 0; foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } if ((_commonUtils as OdbcSqlServerUtils).ServerVersion > 10) { var validx = sql.IndexOf(") VALUES"); if (validx == -1) throw new ArgumentException("找不到 VALUES"); sb.Insert(0, sql.Substring(0, validx + 1)); sb.Append(sql.Substring(validx + 1)); } else { var validx = sql.IndexOf(") SELECT "); if (validx == -1) throw new ArgumentException("找不到 SELECT"); sb.Insert(0, sql.Substring(0, validx + 1)); sb.Append(sql.Substring(validx + 1)); } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try { ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { exception = ex; throw ex; } finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } #if net40 #else public override Task ExecuteAffrowsAsync() => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); public override Task ExecuteIdentityAsync() => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); public override Task> ExecuteInsertedAsync() => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); async protected override Task RawExecuteIdentityAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); long ret = 0; Exception exception = null; try { long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); } catch (Exception ex) { exception = ex; throw ex; } finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } async protected override Task> RawExecuteInsertedAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return new List(); var sb = new StringBuilder(); sb.Append(" OUTPUT "); var colidx = 0; foreach (var col in _table.Columns.Values) { if (colidx > 0) sb.Append(", "); sb.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } if ((_commonUtils as OdbcSqlServerUtils).ServerVersion > 10) { var validx = sql.IndexOf(") VALUES"); if (validx == -1) throw new ArgumentException("找不到 VALUES"); sb.Insert(0, sql.Substring(0, validx + 1)); sb.Append(sql.Substring(validx + 1)); } else { var validx = sql.IndexOf(") SELECT "); if (validx == -1) throw new ArgumentException("找不到 SELECT"); sb.Insert(0, sql.Substring(0, validx + 1)); sb.Append(sql.Substring(validx + 1)); } sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); var ret = new List(); Exception exception = null; try { ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { exception = ex; throw ex; } finally { var after = new Aop.CurdAfterEventArgs(before, exception, ret); _orm.Aop.CurdAfterHandler?.Invoke(this, after); } return ret; } #endif } }