|   |   | 
| 
 | Проблема связки Delphi: TFireDAC+MSSQL+TVP+datetime2(0) | ☑ | ||
|---|---|---|---|---|
| 0
    
        H A D G E H O G s 06.03.23✎ 22:04 | 
        День добрый.
 Понадобился мне вот механизм вставки в MS SQL сервер достаточно больших таблиц данных. 2-ым этим парнем на деревне после BULK INSERT был признан механизм вставки через TVP (табличные параметры процедур). Смысл его в том, что на сервере MS SQL создается табличный тип с колонками, идентичными таблице, куда следует поместить данные, к этому типу – хранимая процедура, которая выполняет помещение через Insert, примерно так: CREATE PROCEDURE [dbo].[Create_ MyTable _TVP] ( @ImportTable dbo.Create_ MyTable _TVPStructure READONLY ) AS SET NOCOUNT ON; SET DATEFORMAT dmy; INSERT INTO dbo.MyTable SELECT * FROM @ImportTable; И все идет отлично, скорость офигенная, но до тех пор, пока я не стал передавать тип DateTime2. Firedac стал выкидывать ошибку назависимо от типа драйвера: [FireDAC][Phys][ODBC][Microsoft][SQL Server Native Client 11.0]Переполнение поля Datetime. Точность в долях секунды превышает масштаб, указанный в привязке параметра. [FireDAC][Phys][ODBC][Microsoft][ODBC Driver 17 for SQL Server]Переполнение поля Datetime. Точность в долях секунды превышает масштаб, указанный в привязке параметра. С типом datetime – ситуация – аналогичная. Я перепробовал уже все мыслимое и немыслимое, все настройки Firedac излазил, ничего не помогает. Проблема в том, что Firedac – крайне трудная в отладке ioba, я уже спустился на уровень SQL Binding, но пока не могу найти причину, или даже настройку округления или точности Firedac. Параметр хранимой процедуры я устанавливаю просто как TDataSet, это не скалярный параметр, и никаких настроек для него я задать не могу: FDStoredProc1.ParamByName('@ImportTable').SetDataSet(FDMemTable1, false); Пока, из ситуации, я вышел, передавая строковые представления дат, а в хранимой процедуре делаю обратную конвертацию через Convert(), но это неправильно. Нужна помощь. Тестовый проект на Delphi 11 выложен тут (просто исходники, никаких dcu, dll, exe): https://github.com/Hadgehogs/DemoTFireDacFail Для работы, необходима Delphi 11 (но, скорее всего, пойдет и более ранняя версия), MS SQL 2019 (но возможно подойдет и более ранняя версия) | |||
| 1
    
        Garykom гуру 06.03.23✎ 22:15 | 
        1. C# вместо Delphi
 https://khalidabuhakmeh.com/passing-table-valued-parameters-from-dotnet-to-sql-server 2. Передавай строку и конверти в хранимке | |||
| 2
    
        H A D G E H O G s 06.03.23✎ 22:19 | 
        (1) Ты невнимательно читал. Давай я повторю:
 "Пока, из ситуации, я вышел, передавая строковые представления дат, а в хранимой процедуре делаю обратную конвертацию через Convert(), но это неправильно." | |||
| 3
    
        Garykom гуру 06.03.23✎ 22:20 | 
        (2) Ну и забей на этом
 Потому что разбираться в древних и уже хреново поддерживаемых технологиях такое себе | |||
| 4
    
        Garykom гуру 06.03.23✎ 22:22 | 
        затести еще CAST вместо CONVERT
 там формат строки под DataTime2 надо подогнать но возможно будет шустрей | |||
| 5
    
        Garykom гуру 06.03.23✎ 22:32 | 
        на C# вроде как пашет, если порядок колонок не нарушать
 https://stackoverflow.com/questions/8335994/ado-net-table-valued-parameter-tvp-operand-type-clash-datetime2-is-incompati | |||
| 6
    
        Кирпич 07.03.23✎ 08:30 | 
        Вроде написано, что масштаб не тот. какой масштаб у DateTime2 в Delphi и SQLServer?
 Тут вабще пишут, что ODBC не понимает DateTime2 https://docwiki.embarcadero.com/RADStudio/Sydney/en/MS_SQL_Server_Questions_(FireDAC) | |||
| 7
    
        Кирпич 07.03.23✎ 08:34 | ||||
| 8
    
        NorthWind 07.03.23✎ 08:46 | 
        а DBGo (ADO) умерло в свежих версиях дельфи?     | |||
| 9
    
        H A D G E H O G s 07.03.23✎ 12:05 | 
        (6) (7) Когда datetime2(0) меняешь на datetime - точно такая же ошибка.     | |||
| 10
    
        H A D G E H O G s 07.03.23✎ 12:05 | 
        (8) Нет.     | |||
| 11
    
        Кирпич 07.03.23✎ 12:13 | 
        (9) А поменять на datetime2(7) ?     | |||
| 12
    
        H A D G E H O G s 07.03.23✎ 12:13 | 
        (11) Точно также     | |||
| 13
    
        NorthWind 07.03.23✎ 12:14 | 
        (10) так может, есть попробовать в этом направлении?
 Все ж посовременнее чем ODBC | |||
| 14
    
        NorthWind 07.03.23✎ 12:15 | 
        * есть смысл     | |||
| 15
    
        H A D G E H O G s 07.03.23✎ 12:21 | 
        (13) dbGo (AdoStoredProc) не умеет работать с параметрами - табличными частями     | |||
| 16
    
        Кирпич 07.03.23✎ 13:06 | 
        поставь полю тип ftTimeStamp     | |||
| 17
    
        H A D G E H O G s 07.03.23✎ 13:50 | 
        (16) Сработало!     | |||
| 18
    
        H A D G E H O G s 07.03.23✎ 13:50 | 
        (16) Это просто попадание наугад или есть инфа или опыт?     | |||
| 19
    
        Кирпич 07.03.23✎ 13:51 | 
        Это гугл     | |||
| 20
    
        H A D G E H O G s 07.03.23✎ 13:51 | 
        (19) Кинь ссылку     | |||
| 21
    
        XLife 07.03.23✎ 14:20 | ||||
| 22
    
        Кирпич 07.03.23✎ 15:20 | ||||
| 23
    
        Кирпич 07.03.23✎ 15:21 | 
        Datetime2    
 SQL_TYPE_TIMESTAMP SQL_TIMESTAMP | |||
| 24
    
        H A D G E H O G s 07.03.23✎ 16:00 | 
        (22) (23) Спасибо!     | |||
| 25
    
        Garykom гуру 07.03.23✎ 16:01 | 
        Потом потребуется передача бинарных данных (например картинки в базе) и тоже упс     | |||
| 26
    
        H A D G E H O G s 07.03.23✎ 16:11 | 
        (25) Не потребуется. Это парсинг Техжурнала.     | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |