Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
Доброго дня всем!
Подскажите, сталкивался кто-нибудь с таким поведением утилиты BCP.
Тестовые данные просты. Процедура, при вызове, добавляет одну строку в таблицу, и возвращает все строки из неё:
+ исходные данные скрипт
use tempdb
go
if object_id ('TestLog') is not null drop table TestLog
go
create table TestLog (id int identity, InsDate datetime default getdate(), SPID int)
go
if object_id ('TestBCP') is not null drop proc TestBCP
go
create procedure TestBCP as
set nocount on
insert TestLog (SPID) values (@@spid)
select cast (id as varchar(100)) as id 
    , convert (varchar (100), InsDate, 114) as InsTime 
    , cast (SPID as varchar(100)) as SPID 
from TestLog
go

при нескольких запусках
bcp "exec tempdb..TestBCP" queryout "test_result.txt" -S (local) -T -c
количество строк в результирующем файле увеличивается на единицу с каждым последующим выполнением, (как и ожидалось).
НО. Если только в параметрах запуска BCP указать форматный файл,
bcp "exec tempdb..TestBCP" queryout "test_result.txt" -S (local) -T -f "test.fmt"
, такого содержания:
11.0
3
1 SQLCHAR 0 100 "\t" 1 ID Cyrillic_General_CI_AS
2 SQLCHAR 0 100 "\t" 2 InsTime Cyrillic_General_CI_AS
3 SQLCHAR 0 100 "\r\n" 3 SPID Cyrillic_General_CI_AS

то при каждом запуске, количество возвращаемых строк увеличивается не на 1, а на 2!
Профайлер показал, что процедура вызывается дважды, в процессе выполнения BCP. Между этими двумя вызовами производится следующее действие:
select convert(binary(5), CollationProperty('Cyrillic_General_CI_AS', 'tdscollation')), convert(binary(5), 
CollationProperty('Cyrillic_General_CI_AS', 'tdscollation')), convert(binary(5), CollationProperty('Cyrillic_General_CI_AS', 'tdscollation'))

Вопрос, можно ли избавиться от двойного вызова процедуры, при использовании форматного файла?
Спасибо.

+ version
select @@version
Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64)
Oct 19 2012 13:38:57
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)

select collation_name from sys.databases where name = 'tempdb'
Cyrillic_General_CI_AS

bcp -v
BCP - Bulk Copy Program for Microsoft SQL Server.
Copyright (C) Microsoft Corporation. All Rights Reserved.
Version: 11.0.2100.60


Вокруг Delphi и SQL
3 окт 14, 15:25    [16656884]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
Первый раз поди процедура вызывается с SET FMTONLY ON? А воторой без него?
3 окт 14, 15:29    [16656923]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Glory
Member

Откуда:
Сообщений: 104760
Uridian
Профайлер показал, что процедура вызывается дважды, в процессе выполнения BCP. Между этими двумя вызовами производится следующее действие:

А там разве не было перед первым вызовом команды SET FMTONLY ON ?
А в TestLog тоже две записи добавляется ?
3 окт 14, 15:31    [16656930]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
не было FMTONLY.
В TestLog записи честно добавляются дважды.
3 окт 14, 15:37    [16656981]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
Для проверки, что не было FMTONLY, изменил тестовый скрипт

use tempdb
go
if object_id ('TestLog') is not null drop table TestLog
go
create table TestLog (id int identity, InsDate datetime default getdate(), FMTONLY_ON bit)
go
if object_id ('TestBCP') is not null drop proc TestBCP
go
create procedure TestBCP as
set nocount on
declare @FMTONLY_ON bit = 0
if (1=0) set @FMTONLY_ON = 1
insert TestLog (FMTONLY_ON) values (@@spid)
select cast (id as varchar(100)) as id 
    , convert (varchar (100), InsDate, 114) as InsTime 
    , cast (@FMTONLY_ON as varchar(100)) as SPID 
from TestLog
go


так вот, при двойном вызове из BCP, обе записи имеют значение 0 (ноль) в поле FMTONLY_ON
3 окт 14, 15:45    [16657073]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
извиняюсь, ошибся. Так правильно
+
use tempdb
go
if object_id ('TestLog') is not null drop table TestLog
go
create table TestLog (id int identity, InsDate datetime default getdate(), FMTONLY_ON bit)
go
if object_id ('TestBCP') is not null drop proc TestBCP
go
create procedure TestBCP as
set nocount on
declare @FMTONLY_ON bit = 0
if (1=0) set @FMTONLY_ON = 1
insert TestLog (FMTONLY_ON) values (@FMTONLY_ON)
select cast (id as varchar(100)) as id 
    , convert (varchar (100), InsDate, 114) as InsTime 
    , cast (FMTONLY_ON as varchar(100)) as SPID 
from TestLog
3 окт 14, 15:47    [16657090]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
Uridian
так вот, при двойном вызове из BCP, обе записи имеют значение 0 (ноль) в поле FMTONLY_ON
Вы, вообще, в курсе, как работает FMTONLY?
3 окт 14, 16:01    [16657240]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
Гавриленко Сергей Алексеевич
Вы, вообще, в курсе, как работает FMTONLY?

Самонадеянно полагаю, да. :) Если не прав, направьте.

первый кусок кода для определения FMTONLY возвращает 0, второй - 1:

+
set fmtonly off
declare @FMTONLY_ON bit = 0
if (1=0) set @FMTONLY_ON = 1
set fmtonly off
select @FMTONLY_ON
go
set fmtonly on
declare @FMTONLY_ON bit = 0
if (1=0) set @FMTONLY_ON = 1
set fmtonly off
select @FMTONLY_ON
3 окт 14, 16:08    [16657296]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
Uridian
Гавриленко Сергей Алексеевич
Вы, вообще, в курсе, как работает FMTONLY?

Самонадеянно полагаю, да. :) Если не прав, направьте.

первый кусок кода для определения FMTONLY возвращает 0, второй - 1:

+
set fmtonly off
declare @FMTONLY_ON bit = 0
if (1=0) set @FMTONLY_ON = 1
set fmtonly off
select @FMTONLY_ON
go
set fmtonly on
declare @FMTONLY_ON bit = 0
if (1=0) set @FMTONLY_ON = 1
set fmtonly off
select @FMTONLY_ON

При FMTONLY_ON не будет вставки данных в таблицу, поэтому вы никогда не увидите записей с FMTONLY_ON = 1.
3 окт 14, 16:20    [16657374]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
Про FMTONLY выяснили, спасибо.
Хорошо бы теперь узнать, как избавиться от двойного вызова в BCP.
3 окт 14, 16:33    [16657451]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Glory
Member

Откуда:
Сообщений: 104760
У меня ваш "test.fmt" не работает
Но даже при падении все равно добавляет лишь одну запись

А вот bcp от sql2000 добавляет 2 записи ). И в профайлере два вызова. Плюс один с FMTONLY.
А узнал я про это потому, что запустил один раз bcp без указания полного пути на нужную версию утилиты

Сообщение было отредактировано: 3 окт 14, 16:55
3 окт 14, 16:53    [16657617]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
Glory, чтобы "test.fmt" заработал, вероятно, следует изменить версию, указанную в первой строке файла.
У меня стоит 11.0
для 2000 SQL-сервера лучше поставить 8.0
3 окт 14, 17:12    [16657749]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
и да, "старые" версии BCP не грешили этим.
Описанное в первом посте поведение проявилось только при замене на "новую" версию.

Повторяю, в профайлере присутствуют ДВА вызова процедуры, И ОБА БЕЗ fmtonly.
Что подтверждается появлением ДВУХ новых записей.
3 окт 14, 17:16    [16657784]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Glory
Member

Откуда:
Сообщений: 104760
Uridian
Glory, чтобы "test.fmt" заработал, вероятно, следует изменить версию, указанную в первой строке файла.
У меня стоит 11.0
для 2000 SQL-сервера лучше поставить 8.0

Дело неи в версии. Он коллейт не может заресолвить. Столбцы то ведь не символьные

Uridian
для 2000 SQL-сервера лучше поставить 8.0

Вы не поняли.
Если запустить bcp на другой версии сервера, то получиться может что угодно.
Вот например bcp 2008R2 выполняет FMTONLY_ON, а bcp 2010 - уже не выполняет.

Так что мысль была про проверку версий сервера и bcp.
3 окт 14, 17:18    [16657795]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
Glory
про проверку версий сервера и bcp.

Связка BCP + SQL Сервер одной версии 2008R2 работала безупречно. Пока не понадобилось добавить в процедуру динамический SQL и временную таблицу. Это сейчас я знаю, что можно было обойти проблему программным способом, а в первый момент, когда бросилось в глаза, что "старый" BCP перестал работать стабильно правильно, а "новый" с виду работал "как надо", было решено проапгрейдить версию BCP и провайдера. Только по прошествии полусуток, выяснилось, что "новый" BCP не совсем... корректен).
Получается что же, это ошибка от Microsoft?
3 окт 14, 17:46    [16657932]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Glory
Member

Откуда:
Сообщений: 104760
Uridian
Получается что же, это ошибка от Microsoft?

Ошибка - это то, что воспроизводится у всех.
У меня ваша ошибка не воспроизводится.

И под проверкой версий я имел ввиду конкретно весрию вашей bcp и вашего сервера.
А не вообще любых возможных вариантов
3 окт 14, 17:48    [16657938]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
Glory
конкретно весрию вашей bcp и вашего сервера.

у меня ошибка воспроизводится для версий

(Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64)) + (BCP Version: 11.0.2100.60)
и
(Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64)) + (BCP Version: 11.0.2100.60)
3 окт 14, 17:56    [16657977]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Glory
Member

Откуда:
Сообщений: 104760
Uridian
у меня ошибка воспроизводится для версий

Начнем с того, что вариант с формат файлом падает...
Microsoft SQL Server 2012 - 11.0.5058.0 (X64) +Version: 11.0.2100.60
3 окт 14, 18:01    [16658007]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
Glory,
Подготовил файл, (влож.)
Скажите, с какой ошибкой у вас падает BCP?

К сообщению приложен файл (test.fmt - 168bytes) cкачать
6 окт 14, 08:45    [16664359]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Glory
Member

Откуда:
Сообщений: 104760
С этим файлом все нормально.
Вернее так.
Подтверждаю, что
BCP Version: 11.0.2100.60 делает 2 вызова, независимо от версии сервера - и для 2012 и для 2008 R2.
BCP Version: 10.50.2500.0 делает 2 вызова, независимо от версии сервера. НО 1ый вызов всегда с FMTONLY ON
Очень похоже на баг
6 окт 14, 10:15    [16664658]     Ответить | Цитировать Сообщить модератору
 Re: Двойной вызов процедуры из BCP с форматным файлом  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 220
Может кто-нибудь из уважаемых форумчан сообщить производителю о баге?
Спасибо.
6 окт 14, 12:54    [16665564]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить