Есть запрос в базу данных, по ответу поддержки "классы EntitySchemaQuery, Select, Insert, Update, Delete это СУБД-независимое API ", исходя из этого был использован InsertSelect. На PostgreSQL запрос отрабатывает отлично, но в Oracle выдает ошибку при использовании TOP в запросе.
Код запроса:
Query selectQuery = new Select(UserConnection)
.Top(numberCountForNumberPool)
.Column(Column.Parameter(request))
.Column(Column.Parameter(currentUserContactId))
.Column(Column.Parameter(currentUserContactId))
.Column("KtSimManagementInitialPoolNumbers", "KtIccid")
.Column("KtSimManagementInitialPoolNumbers", "KtImsi")
.Column("KtSimManagementInitialPoolNumbers", "KtMsisdn")
.Column("KtSimManagementInitialPoolNumbers", "KtName")
.Column(Column.Parameter(cityAndCountNumbersEntity.GetTypedColumnValue(city.Name)))
.Column(Column.Parameter(cityAndCountNumbersEntity.GetTypedColumnValue(note.Name)))
.Column(Column.Parameter(DateTime.UtcNow.Date))
.Column(Column.Parameter(DateTime.UtcNow.Date
.AddDays((int)Core.Configuration.SysSettings.GetValue(UserConnection,
"DayCountForDedicatedPoolNumbers") + 1).AddSeconds(-1)))
.From("KtSimManagementInitialPoolNumbers")
.OrderByAsc("KtSimManagementInitialPoolNumbers", "KtName")
.Join(JoinType.LeftOuter, "KtJasperFullNumberPool")
.On("KtSimManagementInitialPoolNumbers", "KtName")
.IsEqual("KtJasperFullNumberPool", "KtName")
.Where("KtJasperFullNumberPool", "KtName")
.IsNull()
.And("KtSimManagementInitialPoolNumbers", "KtMarketCodeId")
.IsEqual(Column.Parameter(cityForMarketCode));
InsertSelect insertSelectQuery = new InsertSelect(UserConnection)
.Into("KtJasperFullNumberPool")
.Set("KtRequestId", "ModifiedById", "CreatedById", "KtIccid", "KtImsi", "KtMsisdn", "KtName", "KtCityId", "KtNote", "KtReserveDate", "KtReserveToDate")
.FromSelect(selectQuery);
int numberCountInserted = insertSelectQuery.Execute();Подскажите, есть ли возможность использовать в Select для Oracle - TOP для выборки необходимого количества записей в запросе?
Нравится
Проверил, на запросе с Top, OrderByAsc, Join, On, IsEqual, Where отрабатывает нормально. А если добавить колонки с числом и датой из параметра, получим такую же ошибку, как у Вас. Но если, как я выше предложил, дописать «.As», она исчезнет:
var query = new Select(UserConnection)
.Top(2)
.Column("Contact", "Dear")
.Column(Column.Parameter("test")).As("SomeString")
.Column(Column.Parameter(DateTime.UtcNow.Date)).As("SomeDate")
.From("Contact")
.OrderByAsc("Contact", "Dear")
.Join(JoinType.LeftOuter, "Account")
.On("Contact", "AccountId")
.IsEqual("Account", "Id")
.Where("Account", "AnnualRevenueId")
.IsNull() ;
var text = query.GetSqlText();Код генерируется:
SELECT "Dear", "SomeString", "SomeDate"FROM (SELECT "Contact"."Dear", :P1 "SomeString", :P2 "SomeDate"FROM "название_базы"."Contact", "название_базы"."Account"WHERE ("Account"."AnnualRevenueId" IS NULL) AND "Contact"."AccountId" = "Account"."Id"(+)ORDER BY "Contact"."Dear" ASC NULLS FIRST)WHERE (ROWNUM <= 2)Кстати, месяц назад Вы уже об этом спрашивали и я предлагал начать с выяснения мешающей колонки.
Александр, какая именно выдаётся ошибка? Только в Insert Select или просто в Select с Top тоже?
Если перед последней строчкой считать insertSelectQuery.GetSqlText(), что там будет?
Зверев Александр,
в Select тоже, пишет что "
Terrasoft.Common.NullOrEmptyException: Псевдоним колонки запроса не может быть пустым
в Terrasoft.Core.DB.DBEngine.BuildSelectColumnAliasesSqlText(StringBuilder sb, QueryColumnExpressionCollection columnExpressions)
в Terrasoft.DB.Oracle.OracleEngine.BuildSelectQuerySqlText(StringBuilder sb, Select select)
в Terrasoft.Core.DB.DBEngine.BuildQuerySqlText(StringBuilder sb, Select selectQuery)
в Terrasoft.Core.DB.DBEngine.GetQuerySqlText(Select selectQuery)
в Terrasoft.Core.DB.Select.GetSqlText()
в Terrasoft.Configuration.KtReserveNumbersService.ReserveNumbers(Guid request)
в SyncInvokeReserveNumbers(Object , Object[] , Object[] )
в System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
в Terrasoft.Web.Common.ServiceModel.ThreadContextInitializer.Invoke(Object instance, Object[] inputs, Object[]& outputs)
в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
"
А если без этой колонки?
.Column(Column.Parameter(DateTime.UtcNow.Date
.AddDays((int)Core.Configuration.SysSettings.GetValue(UserConnection,
"DayCountForDedicatedPoolNumbers") + 1).AddSeconds(-1)))Или с ней, но сразу после после дописать псевдоним:
.As("MyColumnName")Она самая подозрительная, но если дело не в ней, проверьте и предыдущие.
Зверев Александр, Проверил - при закоментировании колонок разницы нет, но заметил закономерность:
1) если использовать Top без OrderByAsc и Join (ну вчесте с его on, IsEqual, Where) - тогда работает
2) если использовать OrderByAsc или Join (ну вчесте с его on, IsEqual, Where) без Top - тогда работает
3) если использовать Top с OrderByAsc или Join (ну вчесте с его on, IsEqual, Where) - тогда не работает, ошибка
Проверил, на запросе с Top, OrderByAsc, Join, On, IsEqual, Where отрабатывает нормально. А если добавить колонки с числом и датой из параметра, получим такую же ошибку, как у Вас. Но если, как я выше предложил, дописать «.As», она исчезнет:
var query = new Select(UserConnection)
.Top(2)
.Column("Contact", "Dear")
.Column(Column.Parameter("test")).As("SomeString")
.Column(Column.Parameter(DateTime.UtcNow.Date)).As("SomeDate")
.From("Contact")
.OrderByAsc("Contact", "Dear")
.Join(JoinType.LeftOuter, "Account")
.On("Contact", "AccountId")
.IsEqual("Account", "Id")
.Where("Account", "AnnualRevenueId")
.IsNull() ;
var text = query.GetSqlText();Код генерируется:
SELECT "Dear", "SomeString", "SomeDate"FROM (SELECT "Contact"."Dear", :P1 "SomeString", :P2 "SomeDate"FROM "название_базы"."Contact", "название_базы"."Account"WHERE ("Account"."AnnualRevenueId" IS NULL) AND "Contact"."AccountId" = "Account"."Id"(+)ORDER BY "Contact"."Dear" ASC NULLS FIRST)WHERE (ROWNUM <= 2)Кстати, месяц назад Вы уже об этом спрашивали и я предлагал начать с выяснения мешающей колонки.
Зверев Александр,
да, именно Ваша рекомендация с .As("SomeString") помогла когда прописал данный алиас во все колонки где используется "Column.Parameter". Так же в поддержке ответили. Не понял только почему в PostgreSQL это работает без алиаса, а в Oracle без него не так. Но видимо это специфика запросов СУБД, главное что с алиасом работает и там, и там.
Спасибо за помощь!
Передал информацию об этой особенности для освещения в академии.