Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Очень популярная тема (более 25 ответов) FAQ по прямым запросам к данным 1С (число прочтений - 84400 )
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
FAQ по прямым запросам к данным 1С
19. Мая 2006 :: 11:33
Печать  
Ветка перенесена с итланда.
Что-то подверглось небольшому редактированию. Флуд убран.
Что-то потерялось (надеюсь, небезвозвратно), ибо ответ зачастую давался в виде ссылки на ветку. Печаль
« Последняя редакция: 08. Ноября 2006 :: 11:42 - fez »  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #1 - 19. Мая 2006 :: 11:42
Печать  
1)С чего начинать и самый простой пример

Я делаю так:
В глобальном модуле задаем переменную
Перем RecordSet Экспорт;

Инициализируем её (для SQL версии)

[1Cv7]
Процедура ПриНачалеРаботыСистемы()
DataBase = СоздатьОбъект("ODBCDatabase");
DataBase.Attach1C();

RecordSet = СоздатьОбъект("ODBCRecordSet");
RecordSet.SetDatabase(DataBase);
...
КонецПроцедуры
[/1Cv7]

Пишем Функцию

[1Cv7]
Функция глПолучитьВыборку(ODBCRecordset = "",Текст, Отладка=0, Очищать = 1, ТЗ2 = "") Экспорт
   Если ПустоеЗначение(ODBCRecordset) = 1 Тогда
      ODBCRecordset = Recordset;
   КонецЕсли;

   ODBCRecordset.Отладка(Отладка);
   Если ODBCRecordset.Открыть(Текст) = 0 Тогда
      Ошибка = ODBCRecordset.ПолучитьОписаниеОшибки();
      Если ПустоеЗначение(Ошибка) = 0 Тогда
          Сообщить(Ошибка);
      КонецЕсли;
   КонецЕсли;

   Если ПустоеЗначение(ТЗ2) = 1 Тогда
     ТЗ2 = СоздатьОбъект("ТаблицаЗначений");
   КонецЕсли;

  ODBCRecordset.ПолучитьРезультатыВ_ТЗ(ТЗ2, Очищать);
  ODBCRecordset.Закрыть();
 
  Возврат ТЗ2;
КонецФункции
[/1Cv7]


Далее простой пример

[1Cv7]
Текст = "
|SELECT * FROM $Справочник.Номенклатура";

ТЗ = глПолучитьВыборку(, Текст);
ТЗ.ВыбратьСтроку();
[/1Cv7]
  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #2 - 19. Мая 2006 :: 11:43
Печать  
2)Типизация к типам 1С

Текст = "
|SELECT
| Спр.ID as [Элемент $Справочник.Номенклатура]
|FROM
| $Справочник.Номенклатура as Спр
|";

Правило: Типизируем к тому виду который хранится с базе, например
$Справочник.Номенклатура
$Справочник
$Документ.РасходнаяНакладная
$Документ
$Неопределенный
дату, число, строку типизировать не надо

Еще пример

Текст = "
|SELECT
| $Док.Контрагент [Контрагент $Справочник.Контрагенты]
|FROM
| $Документ.ПКО as Док
|";

Соответственно as можно не писать.
  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #3 - 19. Мая 2006 :: 11:44
Печать  
Получение объекта документ неопределенного вида

Для это используем хранимую функцию

Код
Выбрать все
Текст = "create FUNCTION  sp_tohex(@val int, @len1 int) RETURNS varchar(9)
|AS
|begin
|declare @v int;
|declare @tval varchar(9);
|set @v = @val;
|set @tval = '';
|
|while (@v > 0)
|begin
|   set @tval = SUBSTRING('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',1+@v%36,1)+@tval;
|   set @v = @v/36;
|end;
|
|if @tval='' set @tval='0';
|
|while (len(@tval) < @len1)
|begin
|set @tval = ' '+@tval;
|end;
|RETURN(@tval);
|end
|";
RecordSet.Открыть(Текст);
 



Которая будет преобразовывать вид документа из числа в строку

Пример


Код
Выбрать все
Текст = "
|SELECT
|     dbo.sp_tohex(Жур.IDDocDef, 4) + Жур.IDDoc [Док $Документ]
|FROM
|    _1SJourn Жур
|";
 



Получение Документа из Регистра
1) Если в регистре стоит галочка "Быстрая обработка движений" или
есть отбор движений по какому-нибудь измерению или реквизиту, то
в таблице движений регистра есть поле "IDDocDef"

Код
Выбрать все
Текст = "
|SELECT
|     dbo.sp_tohex(Рег.IDDocDef, 4) + Рег.IDDoc [Док $Документ]
|FROM
|    $Регистр.Партии Рег
|";
 



2) В остальных случаях

Код
Выбрать все
Текст = "
|SELECT
|     dbo.sp_tohex(Жур.IDDocDef, 4) + Рег.IDDoc [Док $Документ]
|FROM
|    $Регистр.Партии Рег
|LEFT JOIN _1SJourn Жур ON Жур.IDDoc = Рег.IDDoc
|";
 


  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #4 - 19. Мая 2006 :: 11:47
Печать  
Получение наименования справочника неопр. вида
Конечно в общем случае нельзя. Например есть колонка МПЗ в которой может быть
справочник Номенклатура или Материалы


SQL      
Код
Выбрать все
SELECT
...
COALESCE(СпрН.Descr, СпрМ.Descr) Наименование

LEFT JOIN $Справочник.Номенклатура СпрН ON $ВидСправочника36.Номенклатура + СпрН.ID = $Рег.МПЗ
LEFT JOIN $Справочник.Материалы СпрН ON $ВидСправочника36.Материалы + СпрМ.ID = $Рег.МПЗ
...
 

     
  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #5 - 19. Мая 2006 :: 11:47
Печать  
Выборка документов разного вида

SQL      
Код
Выбрать все
SELECT
$ВидДокумента36.ПКО + ДокП.IDDoc [Док $Документ]
FROM $Документ.ПКО ДокП

UNION ALL

SELECT
$ВидДокумента36.РКО + ДокР.IDDoc [Док $Документ]
FROM $Документ.РКО ДокР
 

  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #6 - 19. Мая 2006 :: 11:49
Печать  
Получение остатков на ТА


1Cv7      
Код
Выбрать все
   ТекстЗапроса = "
   |Select
   |    Товар [Товар $Справочник.Товары],
   |    Склад [Склад $Справочник.Склады],
   |    ОстатокТовараОстаток ОстатокТовара
   |FROM
   |    $РегистрОстатки.ОстаткиТовара(
   |	,
   |	,
   |	Товар in (Select val from #ВыбТовар)
   |				   And
   |	Склад in (Select val from #ВыбСклад),
   |	(Товар, Склад),
   |	ОстатокТовара
   |	) остатки
   |";
   Запрос = СоздатьОбъект("ODBCRecordSet");
   Запрос.УложитьСписокОбъектов(ВыбСклад,"#ВыбСклад","Склады");
   Запрос.УложитьСписокОбъектов(ВыбТовар,"#ВыбТовар","Товары");
   ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
   ТЗ.ВыбратьСтроку();
 

     

  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #7 - 19. Мая 2006 :: 11:50
Печать  
Отбор по пустому значению:

1Cv7      
Код
Выбрать все
Мета=СоздатьОбъект("MetaDataWork");
Элемент = ПолучитьПустоеЗначение("Справочник.Фирмы");
СтрЭлемент=Мета.ЗначениеВСтрокуБД(Элемент); //Именно так в действительности выглядит пустое значение в базе данных

Запрос.УстановитьТекстовыйПараметр("ПустаяФирма",СтрЭлемент);
 



другой вариант предложенный trad'ом такой

1Cv7      

Код
Выбрать все
ник.Фирмы"));
 

     

как ни странно тоже работает вроде...

Начиная с версии 1.8.1.6 появились значения $ПустойИД, $ПустойИД13 -
сответственно пустое значение определенного и неопределенного вида
Пример:
Регистр партии: Фирма - Тип: Справочник.Фирмы, МПЗ - Тип: Справочник

Код
Выбрать все
SELECT
Рег.КоличествоОстаток
FROM $РегистрОстатки.Партии(:ВыбДата~, , Фирма = $ПустойИД AND МПЗ = $ПустойИД13,,)
 

  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #8 - 19. Мая 2006 :: 11:51
Печать  
Группировка результата

1Cv7      
Код
Выбрать все
ТекстЗапроса="|SELECT
   | $Регистр.ОстаткиТоваров.Товар as [Товар $Справочник.Номенклатура],
   | $Регистр.ОстаткиТоваров.Склад as [Склад $Справочник.МестаХранения],
   | SUM($Регистр.ОстаткиТоваров.ОстатокТовара) as Остаток,
   | GROUPING ($Регистр.ОстаткиТоваров.Товар) as Группа1,
   | GROUPING ($Регистр.ОстаткиТоваров.Склад) as Группа2
   |FROM $Регистр.ОстаткиТоваров
   |GROUP BY $Регистр.ОстаткиТоваров.Товар,$Регистр.ОстаткиТоваров.Склад WITH ROLLUP
   |ORDER BY $Регистр.ОстаткиТоваров.Товар,$Регистр.ОстаткиТоваров.Склад,Группа1 DESC,Группа2 DESC
   |";
 


     
На что стоит обратить внимание:
WITH ROLLUP это ключевое слово дает понять что надо добавлять пустые строки с итогами, что очень напоминает нам выгрузку в тз запроса 1С... но строки с итогами добавляются внизу, что нам неудобно.... поэтому добавим две колонки GROUPING... колонка эта ставит единицу если строчка добавлена ROLLUP и 0 если это просто строчка таблицы.... ну и в конце просто отсортируем по товарам, складам, и этим двум колонкам, и таким образом получим привычную нашему взгляду тз запроса 1С.
  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #9 - 19. Мая 2006 :: 11:52
Печать  
Q. Расскажите, каким образом 1С определяет вид данных, находящихся в поле таблицы?

A. У реквизита есть ТИП - это определяет ВСЕ!

Примеры: тип_реквизита - тип_sql - вариант типизации:
Документ.РасходнаяНакладная - char(9) - $Документ.РасходнаяНакладная
Документ - char(13) - $Документ
Неопределенный - char(23) - $Неопределенный

Когда имеем не реквизит, а только идентификатор документа в формате char(9) (скажем из _1sjourn), для того чтобы выполнить типизацию, нам необходимо дополнительное поле с видом документа (не смотря на то, что идентификаторы документов уникальны во всей базе). Если типизирующее имя $Документ и тип поля char(9), то ODBCRecordset ищет дополнительное типизирующее поле, он его определяет как поле с именем типизируемого поля с суффиксом "_вид":
select
ra.iddoc as [ДокументДвижения $Документ], --char(9)
j.iddocdef as ДокументДвижения_вид, --int
  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #10 - 19. Мая 2006 :: 11:54
Печать  
Q. Где базе данных 1С хранятся отборы журналов???
A. В таблице _1SCRDOC для SQL и в файле 1scrdoc.dbf для DBF. Там же находятся подчинённые документы и дополнительные журналы.

Q. Приведите пример использования для формирования реестра документов с разными фильтрами (можно с этими графами - короче как эффективнее, отборы разные - и по шапкам и по табличным частям)
A1. Общий реквизит с отбором.

SQL
Код
Выбрать все
SELECT IDDOC [Документ $Документ], IDDOCDEF Документ_вид
FROM _1SJOURN WHERE ($ОбщийРеквизит.Фирма = :ВыбФирма) AND (_1SJOURN.DATE_TIME_IDDOC Between :НачДата AND :КонДата ~)
 

     

A2. Графа отбора.

SQL      
Код
Выбрать все
SELECT IDDOC [Документ $Документ], IDDOCDEF Документ_вид
FROM _1SJOURN INNER JOIN _1SCRDOC ON _1SJOURN.IDDOC = _1SCRDOC.CHILDID
WHERE (_1SCRDOC.MDID = $ГрафаОтбора.Контрагент) AND (_1SCRDOC.PARENTVAL = :ВыбКонтрагент *) AND (_1SCRDOC.CHILD_DATE_TIME_IDDOC Between :НачДата AND :КонДата ~)
 



A3. Подчинённые документы.

SQL      
Код
Выбрать все
SELECT IDDOC [Документ $Документ], IDDOCDEF Документ_вид
FROM _1SJOURN INNER JOIN _1SCRDOC ON _1SJOURN.IDDOC = _1SCRDOC.CHILDID
WHERE (_1SCRDOC.MDID = 0) AND (_1SCRDOC.PARENTVAL = :ДокРодитель *) AND (_1SCRDOC.CHILD_DATE_TIME_IDDOC Between :НачДата AND :КонДата ~)
 



Q. Как использовать графу отбора по прямым запросам в регистры (обороты)?
A. Смотри A2 для предыдущего вопроса.
  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #11 - 19. Мая 2006 :: 11:55
Печать  
В MSSQL 2000 есть баг связанный с времменными таблицами. Проявляетя в виде замедления проведения документов (1 месяц - 1сек, 2 месяц - 2 сек на документ и т.д.). Ошибка лечится переподключением к БД (вышли и зашли из 1С).
В обход этой проблемы в 1С++ был введен метод ODBCDatabase.ReconnectNaive().

Пример использования:

Код
Выбрать все
База=СоздатьОбъект("ODBCDatabase");

Запрос=СоздатьОбъект("ODBCRecordset");
Запрос.УстановитьТекстовыйПараметр("НачДата",НачДата);
Запрос.УстановитьТекстовыйПараметр("КонДата",КонДата);

ТЗ=Запрос.ВыполнитьИнструкцию("
|select
| iddoc [Документ $Документ],
| iddocdef Документ_вид
|from _1sjourn j (nolock)
|where j.date_time_iddoc between :НачДата and :КонДата~
| and closed = 1
|order by j.date_time_iddoc
|");

ДоковВСеансе=5;
Сч=ДоковВСеансе;
ДокОбъект=СоздатьОбъект("Документ");

ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку()=1 Цикл

ДокОбъект.НайтиДокумент(ТЗ.Документ);
Сообщить(ТЗ.Документ);
ДокОбъект.Провести();

Сч=Сч-1;

Если Сч=0 Тогда
 Сообщить("============================ Реконнект ================================");
 База.ReconnectNative();
 Сч=ДоковВСеансе;
КонецЕсли;

КонецЦикла;
 



Во время выполнение метода должны быть закрыты все курсоры, т.е. все формы справочников, документов, журналов, закрыты все открытые переменные: Док = СоздатьОбъект("Документ").
  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #12 - 19. Мая 2006 :: 11:56
Печать  
Вычисление остатков

Немного теории

Каждый регистр состоит из 2х таблиц: таблицы итогов (RG) и таблицы движений (RA). В таблице итогов хранятся остатки на конец каждого месяца и на ТА. Поэтому чтобы получить остатки на середину месяца нужно делать запрос по 2 таблицам с объединением и группировкой
НО этого делать абсолютно не нужно, т.к. виртуальная таблица $РегистрОстатки или $РегистрОстаткиИобороты это и есть нужный правльный и оптимизированный запрос

P.S. Если вдруг возникнет желание посмотреть, что же эта за виртуальная таблица, то можно воспользоваться методом ODBCRecordSet.Отладка(1)
P.P.S. Хоть в таблице итогов и лежат остатки на конец месяца, то период там стоит равный началу месяца.
Цитата:
Просто счет они ведут не прямым расчетом, а обратным (т.е. не ПРИБАВЛЯЮТ движения от начала до тек. момента, а ВЫЧИТАЮТ из конечных остатков движения от тек. момента до конца). При таком методе расчета последние остатки будут получаться быстрее (а остатки на конец периода - и подавно). А поскольку чаще получают именно остатки более "близкие" к концу периода ("близкие" имеется в виду по кол-ву движений, а не непосредственно по времени), такая схема более эффективна. При этом маркировка особого значения не имеет - и так и так ее придется вычислять. А вычислить дату начала периода удобнее, чем дату конца - посмотрите на ХП _1sp_GetBeginOfPeriod и _1sp_GetNextPeriod, и поймете.
  
Наверх
www  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам.
Ответ #13 - 19. Мая 2006 :: 11:57
Печать  
Вычисление остатков

Теперь практика.

Пример запроса на 1С и 1С++

Код
Выбрать все
|Товар = Регистр.ОстаткиТоваров.Товар;
|Склад = Регистр.ОстаткиТоваров.Склад;
|ОстатокТовара = Регистр.ОстаткиТоваров.ОстатокТовара;
|Функция ОстатокТовараКонОст = КонОст(ОстатокТовара);
|Группировка Товар;
|Условие(Товар в ВыбТовар);
|Условие(Склад в ВыбСклад);
 

     

и

Код
Выбрать все
ТекстЗапроса = "
  |Select
  |    Товар [Товар $Справочник.Товары],
  |    Склад [Склад $Справочник.Склады],
  |    ОстатокТовараОстаток ОстатокТовара
  |FROM
  |    $РегистрОстатки.ОстаткиТовара(
  |	,
  |	,
  |	Товар in (Select val from #ВыбТовар)
  |				   And
  |	Склад in (Select val from #ВыбСклад),
  |	(Товар, Склад),
  |	ОстатокТовара
  |	) остатки
  |";
  Запрос = СоздатьОбъект("ODBCRecordSet");
  Запрос.УложитьСписокОбъектов(ВыбСклад,"#ВыбСклад","Склады");
  Запрос.УложитьСписокОбъектов(ВыбТовар,"#ВыбТовар","Товары");
  ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
  ТЗ.ВыбратьСтроку();
 



Конечно в этих запросах есть немного отличий, а именно в обработке пустых фильтров. В прямом запросе результат будет пустой
  
Наверх
www  
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: FAQ по прямым запросам.
Ответ #14 - 07. Ноября 2006 :: 09:25
Печать  
Пара ссылок, представляющих интерес в плане особенностей применения:

Расчет остатков на документ и по документ (пост №5 trad)
http://www.1cpp.ru/forum/YaBB.pl?num=1162733649/5#5

Текущие особенности и порядок деинициализации объектов ODBCRecordSet и ODBCDataBase
http://www.1cpp.ru/forum/YaBB.pl?num=1162472281/8#8 (пост №8 Quan)
« Последняя редакция: 13. Ноября 2006 :: 18:56 - kms »  

De quelle planète es-tu?
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: FAQ по прямым запросам к данным 1С
Ответ #15 - 13. Ноября 2006 :: 18:59
Печать  
Об использовании set nocount в хранимых процедурах (ссылка на itland):

http://itland.ru/forum//index.php?showtopic=12960
http://itland.ru/forum//index.php?act=ST&f=8&t=12735
  

De quelle planète es-tu?
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: FAQ по прямым запросам к данным 1С
Ответ #16 - 15. Ноября 2006 :: 12:31
Печать  
Кладовая строк подключения (Славко, thnx): http://www.connectionstrings.com/
Работа с Excel c помощью ODBC и OLEDB http://www.1cpp.ru/forum/YaBB.pl?num=1163586032
« Последняя редакция: 18. Ноября 2006 :: 09:19 - kms »  

De quelle planète es-tu?
Наверх
 
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам к данным 1С
Ответ #17 - 12. Января 2007 :: 10:05
Печать  
Сборник курсов на сайте "Интернет-Университет"
http://www.intuit.ru/courses.html

Смотри внизу: "Технологии баз данных"
Data Mining  http://www.intuit.ru/department/database/datamining/
SQL Server 2000  http://www.intuit.ru/department/database/sqlserver2000/
Информация о курсе
В курсе содержатся все необходимые сведения об установке, конфигурировании и эксплуатации SQL 2000 Server для профессионалов в области информационных технологий.
Рассматриваются вопросы установки и конфигурирования SQL Server, создания баз данных и объектов, использования Microsoft Cluster Services (MSCS), манипулирования данными, администрирования и использования SQL Server, управления с помощью T-SQL таблицами, триггерами, базами данных, доступа к SQL Server через Internet, настроек и особенностей применения репликаций, Microsoft Distributed Transaction Coordinator (MS DTC), работы с аналитическими службами SQL Server. Рассмотрены типичные проблемы, связанные с эксплуатацией SQL Server, и способы их решения.

SQL и процедурно-ориентированные языки  http://www.intuit.ru/department/database/cdba/
Введение в модель данных SQL  http://www.intuit.ru/department/database/sqlmdintro/
Введение в реляционные базы данных  http://www.intuit.ru/department/database/sql/
Основы SQL  http://www.intuit.ru/department/database/sql/
Основы проектирования приложений баз данных  http://www.intuit.ru/department/database/cdba2/
Основы работы с базами данных http://www.intuit.ru/department/database/basedbw/

ПС. Ищите в лекции ссылку "для печати и PDA"http://www.intuit.ru/department/database/sql/1/sql_1.html
Лекция развернется полностью.....
« Последняя редакция: 22. Мая 2007 :: 06:16 - trdm »  
Наверх
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам к данным 1С
Ответ #18 - 07. Марта 2007 :: 08:46
Печать  
Q: При выполнении параметризированного запроса при помощи OLEDBData/OLEDBCommand через vfpoledb provider v9 возникает ошибка:
Цитата:
Произошли ошибки во время выполнения многошаговой операции OLE DB. По возможности, проверьте значения всех состояний OLE DB. Работа не выполнена.

или
Цитата:
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.

или
Цитата:
[One or more accessor flags were invalid]: Недопустимый клиент доступа

Что делать?

A: Почитать об этой ошибке в базе знаний MS: http://support.microsoft.com/kb/269495
Положение исправляется добавлением в реестр ключа:
В ветку [HKEY_CLASSES_ROOT\CLSID\{50BAEED9-ED25-11D2-B97B-000000000000}] добавить ключ "OLEDB_SERVICES"=dword:00000000 . Если этот ключ уже есть, то нужно значение установить в 0 (ноль).
« Последняя редакция: 03. Июля 2007 :: 10:18 - spock »  
Наверх
ICQ  
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам к данным 1С
Ответ #19 - 18. Мая 2007 :: 15:24
Печать  
Q. Как можно в запросе заставить драйвер FoxPro
использовать индексы? Используется доступ через oledb.
A. Возможно проблема связана с режимом сортирировки
"каждый индекс в отдельности запоминает тот режим сортировки при котором он был создан "
http://www.foxclub.ru/articles/index.php?id=35
изменените в строке подключения
Код
Выбрать все
|Collating Sequence=RUSSIAN; 


на
Код
Выбрать все
|Collating Sequence=MACHINE;  


PS. Федор, отформатируй пожалуйста  с пом [ c o d e ] 1 и 2-й посты.
  
Наверх
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам к данным 1С
Ответ #20 - 09. Августа 2007 :: 07:54
Печать  
Букварь по MS VFP 9 в формате "chm".
http://rapidshare.com/files/45881708/www_foxclub_ru2.2.chm.html
  
Наверх
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам к данным 1С
Ответ #21 - 17. Октября 2007 :: 12:33
Печать  
  
Наверх
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам к данным 1С
Ответ #22 - 17. Октября 2007 :: 12:35
Печать  
connectionstrings.com в формате chm
  

connectionstrings_com.rar ( 136 KB | Загрузки )
Наверх
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам к данным 1С
Ответ #23 - 22. Октября 2007 :: 20:45
Печать  
http://slil.ru/25011738
Публикации по SQL Серверу с sql.ru в формате *.chm
  
Наверх
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: FAQ по прямым запросам к данным 1С
Ответ #24 - 22. Февраля 2008 :: 12:01
Печать  
Мини faq по прямым  запросам для ДБФ (через FoxPro)

1.      Как правильно написать строку подключения?
http://www.1cpp.ru/forum/YaBB.pl?num=1194117946

2.      Где взять драйвер vfpoledb.dll ?
http://www.microsoft.com/downloads/details.aspx?FamilyId=E1A87D8F-2D58-491F-A0FA...

или поиск по ключевому слову VFPOLEDBSetup.msi

3.      Можно ли использовать прямые запросы в модуле документа?
Как сделать, чтобы запросы  не блокировали таблицы?

в строке подключения указать параметр
Код
Выбрать все
TABLEVALIDATE=0; 


или после подключения выполнить команду
Код
Выбрать все
ОледбКоманда.Выполнить("Exec('SET TABLEVALIDATE TO 0')"); 


см подробнее http://www.1cpp.ru/forum/YaBB.pl?num=1237895266/5
http://www.1cpp.ru/forum/YaBB.pl?num=1230361378

4. Где я могу почитать документацию по FoxPro ?
от разработчика http://msdn2.microsoft.com/en-us/library/aa468129.aspx
на русском       http://www.foxclub.ru/rhproject/project/
ввиде chm       http://www.1cpp.ru/forum/YaBB.pl?num=1185783552

5.      Можно ли использовать временные таблицы?
Что мне делать, если мне нужен запрос по складам – всем вошедшим в запрос,
ведь я заранее не знаю этот список складов?

http://www.1cpp.ru/forum/YaBB.pl?num=1188673318

6.      Могу ли я использовать индексы в запросе ?
Я использую прямой запрос, но родной 1С метод СводныйОстаток() выполняется быстрее, что я делаю не так?

http://www.1cpp.ru/forum/YaBB.pl?num=1184317705/30#31

7.      Могу ли я использовать Хранимые процедуры?
Как получить время из поля TIME журнала (ДБФ)?

http://www.1cpp.ru/forum/YaBB.pl?num=1180606447

8.      Могу ля использовать представления (View) ?

http://www.1cpp.ru/forum/YaBB.pl?num=1183553285/25#25 (до конца не изучен)

9.      Могу ли я использовать команды FoxPro или только запросы?

     Пример http://www.1cpp.ru/forum/YaBB.pl?num=1178779637/29#29

10.      Могу ли я писать запрос сразу к двум базам?
Я использую OLE-соединение, но это очень медленно, что можно сделать?

http://www.1cpp.ru/forum/YaBB.pl?num=1182497837/19#19

11.      Как задать константу в запросе?
'Моя строковая константа'
[Моя строковая константа]
{^2008-01-01}  константа типа дата

12.      А пустые значения?

$ПустойИД  и т.п. – для документов и справочников
{^0000-00-00} – для дат

13. Как получить Id реквизита справочника (fieldid) ?
Код
Выбрать все
глМД = СоздатьОбъект("MetaDataWork");
ИДЮрАдрес = Прав(_IDToStr(глМД.ИДРеквизитаСправочника("ЮрЛица","ЮрАдрес")),4); 


14.      Как хранятся длинные строки, ведь в ДБФ нет BLOB полей?

В таблицах 1SBLOB и 1SCONST есть поле blockno – длинные строки разбиваются на строки одинаковой длины и в этом поле пишется номер блока. Первые 9 символов
нулевого блока задают длину строки.

15.      Могу ли я отлаживать запросы?
Можно установить FoxPro и там отлаживать.
Предварительно запрос нужно преобразовать
Код
Выбрать все
глМД = СоздатьОбъект("MetaDataWork");
ТекстЗапросаДляFoxPro=глМД.ОбрМетаСКЛ(ТекстЗапроса); 

Также FoxPro сообщит в отдельном окне о возжности оптимизации выполнения, варианты
FULL, None... Если None на небольшом наборе данных - это значит плохо составленный запрос.

16. Мне нужно выбрать документы только по определенный документ(На).
Получаем позицию стандартно :
Код
Выбрать все
ПозицияДок=ВыбДок.ПолучитьПозицию();
ПозицияДокСтр=Мд.ПолучитьДатуВремяИдДок(ПозицияДок); 


Аналогом поля DATE_TIME_IDDOC в ДБФ является выражение DTOS(Жур.date)+Жур.time+Жур.iddoc где Жур - 1SJourn т.е. в запросе
Код
Выбрать все
WHERE  DTOS(Жур.date)+Жур.time+Жур.iddoc<:ПозицияДокСтр 


по выражению построен индекс , т.е. его использование достаточно эффективно. Аналогично в регистрах.

17.      Какие основные отличия  запросов SQL и ДБФ ?
а. Виртуальные таблицы  не поддерживаются в ДБФ.
б. Некоторые таблицы в SQL варианте начинаются с «_» : 1SJourn и _1SJourn
в. Вместо поля DATE_TIME_IDDOC используется date в FoxPro
г. в ДБФ  - РегКассаНач.period = :ПредМесяц~~, в SQL - РегКассаНач.period = :ПредМесяц
д. В Fox служебные слова нерегистрозависимы
е. Вместо CASE используется функция ICASE
ж. В Fox нет (NOLOCK) и GROUPING
з. Специфические функции Fox как правило не поддерживаются в SQL.
дополнительные сведения см. в документации(http://www.1cpp.ru/forum/YaBB.pl?num=1185783552) к Fox раздел "Масштабирование Базы Данных Visual FoxPro в Базу Данных SQL Server"
« Последняя редакция: 07. Декабря 2012 :: 08:24 - kiruha »  
Наверх
 
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: FAQ по прямым запросам к данным 1С
Ответ #25 - 19. Августа 2008 :: 13:51
Печать  
Q. При запросе из нескольких таблиц, какое соединение выбрать: внутреннее, или внешнее левое?

A. http://www.1cpp.ru/forum/YaBB.pl?num=1217939813/21#21

Цитата:
Ну вы что, господа? Первый раз замужем чтоли? Это же старая, известная фишка любых sql серверов.

Если несколько источников данных соединяются внутренним соединением (inner join), то оптимизатор запросов получает дополнительное пространство для раздумий: первичный проход можно делать по любому из источников данных, а данные из остальных источников выбираются букмарк лукапом, при этом отдается предпочтение кластерным индексам.
select
    t1.f1
    t2.f2
from t1
inner join t2 on t1.id = t2.id
where t1.d > 3 and t1.d < 23 and t2.f2 = 234

Предположим, что есть индекс по полю d, и кластерные индексы по полям id.
Такой запрос имеет два очевидных, конкурирующих плана выполнения:
1)Переход по индексу (Index seek) t1.d по условию t1.d > 3; проход по индексу до условия t1.d < 23; при проходе выполняя два перехода по кластерным: Bookmark lookup во-первых для t1 чтобы достать поле f1, во-вторых для t2 чтобы достать поле f2. Оптимизатор считает Bookmark lookup весьма тяжелой операцией.
2)пройти по кластерному индексу t2.id с условием t2.f2 = 234; и сделать для выбранных записей один переход по кластерному: Bookmark lookup в первичную таблицу t1, для получения f1 и оценки сразу всех остальных условий t1.d > 3 and t1.d < 23, а если еще в базе будет индекс по полю t2.f2, тогда вообще фиг знает какой план победит (скорее этот).

При этом оптимизатору предписано оценить эффективность различных вариантов плана выполнения по нескольким критериям (количество чтений, количество внутренне передаваемых данных, типы операций, утилизация проца и т.п., там разные коэффициенты по разным критериям). А как он (оптимизатор) это делает, если запрос еще только предстоит исполнить? Это делается на основе статистики. А статистика вещь хорошая только когда она в надлежащем состоянии. К сожалению не редки случаи когда на основе не объективной статистики (да и коэффициенты тоже людьми проставлены) и в пограничных вариантах оптимизатор выбирает не тот план выполнения. (Кстати на SQL 2005 оптимизатор в этом отношении умнее)

Вернемся к нашему примеру: если мы заранее знаем характер наших данных, то чтобы оптимизатор даже не сомневался, какую таблицу выбрать в качестве основы выборки, мы можем указать левое соединение вместо внутреннего:
select
    t1.f1
    t2.f2
from t1
left join t2 on t1.id = t2.id
where t1.d > 3 and t1.d < 23 and t2.f2 = 234

Тогда у оптимизатора не остается выбора: основной таблицей с которой он начнет проход будет t1 (точнее даже это будет таблица индекса t1.d).
  
Наверх
www  
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: FAQ по прямым запросам к данным 1С
Ответ #26 - 22. Августа 2008 :: 09:48
Печать  
Q. OLEDB. Соединение с источником для ряда строк завершается с ошибкой:
Код
Выбрать все
СтрокаСоединения="Provider=VFPOLEDB.1;Deleted=Yes;Data Source="+Каталог+";Mode=ReadWrite;Extended Properties="";User ID="";Password="";Mask Password=False;Collating Sequence=Machine;DSN=""";
Рез=БД.Соединение(СтрокаСоединения);
 



Код
Выбрать все
FAILED! IDataInitialize::GetDataSource(): Format of the initialization string does not conform to the OLE DB specification.
 



A. http://www.1cpp.ru/forum/YaBB.pl?num=1219395692

Alex_Bob писал(а) 22. Августа 2008 :: 09:01:
Как известно, если в строке подключения для VFP OLEDB 9.0Sp.2 указать "Deleted=Yes", то вываливается ошибка:
FAILED! IDataInitialize::GetDataSource(): Формат строки инициализации не соответствует спецификации OLE DB.

Путем логического подбора  Улыбка установлено, что нормально проходит строка "Set Deleted=Yes"

  

De quelle planète es-tu?
Наверх
 
IP записан
 
leov-001
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 150
Зарегистрирован: 05. Марта 2009
Re: FAQ по прямым запросам к данным 1С
Ответ #27 - 24. Марта 2009 :: 05:34
Печать  
     
     
Код
Выбрать все
СтрокаСодинния = "
	|Provider=VFPOLEDB.1;
	|Deleted=-1;
	|Null = Yes;
	|Exclusive = No;
	|SourceType = DBF;
	|Data Source=" + КаталогИБ() + ";
	|Mode=ReadWrite;
	|Extended Properties="""";
	|User ID="""";
	|Password="""";
	|Mask Password=False;
	|Collating Sequence=MACHINE;
	|DSN="""""; 


У меня ни "Set Deleted=Yes" ни "Deleted=Yes" не катит, выдает ошибку FAILED! IDataInitialize::GetDataSource(): Формат строки инициализации не соответствует спецификации OLE DB.

Пишу так Deleted=0 - Показывает удаленные записи, Deleted=-1 - НЕ показывает удаленные записи

  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: FAQ по прямым запросам к данным 1С
Ответ #28 - 14. Июля 2009 :: 10:08
Печать  
Описание таблиц 1С, их структуры, полей,
подсистемы справочников, регистров, документов


http://www.script-coding.info/v77tables.html

Бухгалтерская подсистема

http://www.1csql.ru/materials/articles/develop.html~ed7512c5-4b62-fb0e-5c98-b198...
« Последняя редакция: 29. Октября 2009 :: 10:38 - kiruha »  
Наверх
 
IP записан
 
Sciff
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 8
Зарегистрирован: 04. Октября 2013
Re: FAQ по прямым запросам к данным 1С
Ответ #29 - 14. Октября 2013 :: 09:09
Печать  
Доброго времени суток, есть такой вопрос:
Прямым запросом нужно выбрать за период документы реализации и все подчиненные им документы, у подчиненных документов нужно просуммировать, например, колонку "Количество". В итоге сумму передать в запрос по реализации, как выбираемое поле (Вся выборка должна быть в одном запросе).
Схематично запрос:
Выбрать
   Реализация
  ,(Выбрать
       СуммаКоличествоПодчиненныеДоки
    ИЗ
       _1SCRDOC
   ЕСЛИ ЗначениеОтбора = Реализация
   ) как Кол
ИЗ Журнал
Запрос описал схематично, дабы показать что зачем хочу выбирать, но вот голову сломал не получается.
Отдельно написал запрос по выборке подчиненных и сумме по "Количеству" передаю параметром реализацию, работает. Пытаюсь прикрутить к запросу, где выбираю реализацию и передать ее в подзапрос, ничего не возвращает.
Как реализовать этот момент. Очень надо. Буду очень благодарен.
Вот вариант запроса:
Код
Выбрать все
SELECT Реализация.IDDOC [Ссылка $Документ.Реализация]
	,  (Подзапрос.Кол) Кол
FROM _1SJOURN AS Журнал With (NOLOCK)
	INNER JOIN $Документ.Реализация AS Реализация With (NOLOCK) ON Журнал.IDDOC = Реализация.IDDOC
	CROSS JOIN (SELECT
			  (Подзапрос.Кол) Кол
		FROM _1SCRDOC AS Отбор With (NOLOCK)
			CROSS JOIN (SELECT
					  (CASE WHEN Журнал.IDDOCDEF = $ВидДокумента.РасходСоСклада THEN Подзапрос.СуммаКоличество ELSE Подзапрос1.СуммаКоличество END) Кол
					,Журнал.IDDOC Документ
					FROM _1SJOURN AS Журнал With (NOLOCK)
					LEFT OUTER JOIN (SELECT РасходСоСкладаСтроки.IDDOC Ссылка
							, Sum($РасходСоСкладаСтроки.Количество) СуммаКоличество
						FROM $ДокументСтроки.РасходСоСклада AS РасходСоСкладаСтроки With (NOLOCK)
						GROUP BY РасходСоСкладаСтроки.IDDOC) AS Подзапрос ON Журнал.IDDOC = Подзапрос.Ссылка
					LEFT OUTER JOIN (SELECT СторноРасходаСоСкладаСтроки.IDDOC Ссылка
							, Sum($СторноРасходаСоСкладаСтроки.Количество) СуммаКоличество
						FROM $ДокументСтроки.СторноРасходаСоСклада AS СторноРасходаСоСкладаСтроки With (NOLOCK)
						GROUP BY СторноРасходаСоСкладаСтроки.IDDOC) AS Подзапрос1 ON Журнал.IDDOC = Подзапрос1.Ссылка
				WHERE (Журнал.IDDOCDEF = $ВидДокумента.РасходСоСклада)
					OR (Журнал.IDDOCDEF = $ВидДокумента.СторноРасходаСоСклада)))  AS Подзапрос ON Отбор.CHILDID = Подзапрос.Документ
		WHERE (Отбор.PARENTVAL = Реализация.IDDOC) AS Подзапрос
WHERE (Журнал.IDDOC = :ТекДок) 


Код создан в консольке, т.к. только осваиваю прямые запросы...
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать