Здравствуйте, Sinclair, Вы писали:
S>Про learning pipeline ничего не могу сказать — никогда не сталкивался. S>Но никаких принципиальных ограничений на то, чтобы запихать внутрь сервера произвольный дотнет код и исполнять его в рамках apply или ещё каких конструкций я не вижу.
А каков механизм вызова этого кода, можно на простейший исходный код посмотреть?
Собсно, достаточно показать сигнатуру произвольной ф-ии с пустым телом и пример её вызова из батча или процедуры.
Re[101]: В России опять напишут новый объектно-ориентированны
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, Sinclair, Вы писали:
S>>Про learning pipeline ничего не могу сказать — никогда не сталкивался. S>>Но никаких принципиальных ограничений на то, чтобы запихать внутрь сервера произвольный дотнет код и исполнять его в рамках apply или ещё каких конструкций я не вижу.
V>А каков механизм вызова этого кода, можно на простейший исходный код посмотреть? V>Собсно, достаточно показать сигнатуру произвольной ф-ии с пустым телом и пример её вызова из батча или процедуры.
Здравствуйте, Sinclair, Вы писали:
S>>>Про learning pipeline ничего не могу сказать — никогда не сталкивался. S>>>Но никаких принципиальных ограничений на то, чтобы запихать внутрь сервера произвольный дотнет код и исполнять его в рамках apply или ещё каких конструкций я не вижу. V>>А каков механизм вызова этого кода, можно на простейший исходный код посмотреть? V>>Собсно, достаточно показать сигнатуру произвольной ф-ии с пустым телом и пример её вызова из батча или процедуры.
S>Пример функции — https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration-database-objects-user-defined-functions/clr-table-valued-functions?view=sql-server-2017
))
Я хотел, чтобы не по ссылке, а прямо здесь была нарисована вся эта "красота":
[Microsoft.SqlServer.Server.SqlProcedure]
public static void CreateNewRecordProc()
{
// Variables.
SqlDataRecord record;
// Create a new record with the column metadata. The constructor
// is able to accept a variable number of parameters.
record = new SqlDataRecord(new SqlMetaData("EmployeeID", SqlDbType.Int),
new SqlMetaData("Surname", SqlDbType.NVarChar, 20),
new SqlMetaData("GivenName", SqlDbType.NVarChar, 20),
new SqlMetaData("StartDate", SqlDbType.DateTime) );
// Set the record fields.
record.SetInt32(0, 0042);
record.SetString(1, "Funk");
record.SetString(2, "Don");
record.SetDateTime(3, new DateTime(2005, 7, 17));
// Send the record to the calling program.
SqlContext.Pipe.Send(record);
}
А то здесь недавно были споры насчёт "аналога" из мира Oracle, но эти подходы, ИМХО, несравнимы:
Единственно, где в Джава имеет смысл опускаться на уровень "механики" — это в pipelined-функциях, чтобы обрабатывать данные оперативно, а не через накопление промежуточных больших наборов. Т.е. тут хоть причина есть.
Re[103]: В России опять напишут новый объектно-ориентированны
V>Единственно, где в Джава имеет смысл опускаться на уровень "механики" — это в pipelined-функциях, чтобы обрабатывать данные оперативно, а не через накопление промежуточных больших наборов. Т.е. тут хоть причина есть.
Ну, если честно, то конкретно этот пример красив с т.з. языка (хотя, имхо, использование "context connection=true" чище, чем хранение собственных креденшлов внутри кода хранимой процедуры), но с т.з. здравого смысла — ужос-ужос. Ну, то есть если мы хотим сделать table-valued функцию, которая возвращает нам данные из hrSchema.EmployeeTable, то её лучше писать на SQL — чтобы оптимизатор "видел" её тело и мог выполнять глобальные оптимизации.
Парням из Редмонда явно не ставили задачей такой сценарий вообще — там либо ты читаешь данные из базы, и тогда всё хорошо.
Либо ты прямо возвращаешь табличные данные, и ты сам виноват
Было бы интересно посмотреть, как сделано в "мире Оракл" возвращение полностью синтезированного табличного значения. Подозреваю, что будет не сильно красивее — ведь аналоги SQLMetaData откуда-то должны взяться. Это в этом примере мы сэкономили на том, что нам ResultSet построили автоматом.
Вообще видно, что SQL Server Team дали первую версию дотнета и велели сварганить что-то для интеропа.
Ну, вот они и сварганили — без дженериков, на коленке, как смогли.
Я думаю, что их первое предложение по TVF было ещё кошмарнее, но им сказали "есть же IEnumerable — ну-ка встали, и пошли использовать IEnumerable".
Вот они и прикрутили "типизатор" к IEnumerable, как умели.
Кастом агрегаты бы тоже сильно выиграли от использования дженериков — тогда очевидные косяки выявлялись бы на этапе компиляции, а не загрузки в сервер.
В общем, по-хорошему им надо было бы сделать некий revisit этому подходу — а заодно поковырять C# 7.3 и RyuJIT на предмет удешевления маршаллинга.
Но есть подозрение, что спрос на эту функциональность — околонулевой; поэтому выделить на неё ресурсы не выходит.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[104]: В России опять напишут новый объектно-ориентированны
Здравствуйте, Sinclair, Вы писали:
S>Было бы интересно посмотреть, как сделано в "мире Оракл" возвращение полностью синтезированного табличного значения. Подозреваю, что будет не сильно красивее — ведь аналоги SQLMetaData откуда-то должны взяться.
Есть разные подходы, в том числе когда схему табличной ф-ии полностью описывают ручками в коде.
А есть неплохо автоматизированный базовый класс UDF, где в наследнике необходимо описать действия лишь в пересчёте на строчку, а вся метаинформация с т.з. программиста "берется откуда-то сверху":
(кратко, только суть)
create function properties()
returns table (property varchar(500), value varchar(500))
external name 'JVMProperties.dump' language java
public class JVMProperties extends UDF {
Enumeration propertyNames;
Properties properties ;
public void dump (String property, String value) throws Exception
{
int callType = getCallType();
switch(callType) {
case SQLUDF_TF_OPEN:
properties = System.getProperties();
propertyNames = properties.propertyNames();
break;
case SQLUDF_TF_FETCH:
if (propertyNames.hasMoreElements()) {
property = (String) propertyNames.nextElement();
value = properties.getProperty(property);
set(1, property);
set(2, value);
} else {
setSQLstate("02000");
}
break;
case SQLUDF_TF_CLOSE:
break;
}
}
}
Re[103]: В России опять напишут новый объектно-ориентированны
V>Единственно, где в Джава имеет смысл опускаться на уровень "механики" — это в pipelined-функциях, чтобы обрабатывать данные оперативно, а не через накопление промежуточных больших наборов. Т.е. тут хоть причина есть.
разве в оаракле так делают ? лет 15 назад я смотрел на SQLJ stored procedures, там нормальный sql уже был, а не стринги с бомбой в рантайме. плюс уходил вся та муть с conn, prepare, execute и прочее техническое.
V>Ты же понимаешь, что математически вот этот предикат абсурден: IS NOT NULL?
В данном случае все корректно.
V>(если взять принятый в математике и IT способ аппликации ф-ий/операторов)
В математике есть право- и лево- ассоциативные операторы.
Так вот произведение операторов IS и NOT порождает оператор ISN'T := IS NOT
V>Чему равно выражение (NOT NULL)? ))
Здесь неверно стоят скобки. Выраражение на самом деле (IS NOT) NULL.
V>Т.е. вот отправляется запрос на сервер и уже оба ендпоинта должны заранее знать тип возвращаемого результата, а не гнать каждый раз метаинформацию и интерпретировать её на каждой из сторон.
Вообще-то в современных SQL так и происходит:
SQL запрос проходит стадию компиляции, оптимизации, затем в него подставляются параметры.
Откомпилированый запрос можно переиспользовать (API для этого есть по крайней мере в MySQL, PostgeSQL, sqlite...) неограничченное число раз с разными параметрами.
Для совместимости также обычно оставляют one-shot API типа exec_sql или PQexec... но никто не заставляет использовать именно это API.
Здравствуйте, eskimo82, Вы писали:
E>SQL запрос проходит стадию компиляции, оптимизации, затем в него подставляются параметры. E>Откомпилированый запрос можно переиспользовать (API для этого есть по крайней мере в MySQL, PostgeSQL, sqlite...) неограничченное число раз с разными параметрами.
Но это всё верно для многократных вызовов одного и того же запроса.
Получается что-то типа JIT, со всеми известными плюсами и минусами.
Только в реальности такой "JIT" выполняется каждый раз заново, бо хранить пул объектов Command на клиенте не принято.
Re[105]: В России опять напишут новый объектно-ориентированны
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, Sinclair, Вы писали:
S>>Было бы интересно посмотреть, как сделано в "мире Оракл" возвращение полностью синтезированного табличного значения. Подозреваю, что будет не сильно красивее — ведь аналоги SQLMetaData откуда-то должны взяться.
V>Есть разные подходы, в том числе когда схему табличной ф-ии полностью описывают ручками в коде.
V>А есть неплохо автоматизированный базовый класс UDF, где в наследнике необходимо описать действия лишь в пересчёте на строчку, а вся метаинформация с т.з. программиста "берется откуда-то сверху": V>(кратко, только суть) V>
V> create function properties()
V> returns table (property varchar(500), value varchar(500))
V> external name 'JVMProperties.dump' language java
V>
Ну, если честно — тоже выглядит достаточно кошмарно, практически так же, как в случае MS SQL. Склеили Init и FillRow в один dump со свитчем, искусственно припилили выходную сигнатуру к входной (в дотнете хотя бы параметры имеют модификатор out, показывая направление передачи).
Можно было бы сделать сильно лучше и там, и там. Вообще реализация в SQL Server направлена в более правильную сторону, но уж очень недалеко ушла — в том смысле, что чётко разведены фазы "подготовки" и "возврата", что позволяет серверу выбирать стратегии исполнения и, потенциально, статически валидировать косяки вроде попытки быстренько прочитать данные из базы в тот момент, когда коннекта уже нету.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[42]: В России опять напишут новый объектно-ориентированны
Здравствуйте, IB, Вы писали:
_>> А можно теперь озвучить в какому году появилась та версия (в которой добавили InnoDB), начиная с которой проблем нет? IB>По дефолту? Кажется, середина 16-го года.
По-дефолту...
В стандартной поставке с 2003-го года, т.е. примерно столько, сколько живёт RSDN. ))
Включается одной строкой в конфиге: default-storage-engine = InnoDB