Apico Soft / АПИКО Софт



Спонсором блога ScalaHelp.RU является компания АПИКО Софт.

Мы предоставляем:
- Качественный ERP консалтинг.
- Внедрение и сопровождение системы.
- Российские формы первичных документов, бухгалтерская и налоговая отчетность.

- Разработка корпоративной отчетности.

Наш телефон 8 (495) 961 98 48
Сайт http://www.apicosoft.ru/

Позвоните нам, мы сделаем все, чтобы помочь Вам.

среда, декабря 23, 2009

Загрузка курсов валют

Каждый день требуется загрузить в систему курсы валют. Операция простая, но достаточно муторная, плюс ошибки ввода и забывчивость пользователей.

В качестве источника данных по курсам валют можно использовать специальный веб-сервис Центрального Банка России. http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx

Дальше я пробегусь по вариантам автоматизации задачи в Scala.

Epicor Service Connect (ESC)

Сразу скажу, что использование ESC для данной задачи – самое правильное решение, т.к. все делается исключительно с использованием стандартной функциональности, никакой самодеятельности. Правда, далеко не у всех есть в лицензии эта опция.

Лирическое отступление: если у вас есть сопряжение с другими системами, если требуется создавать документы или делать какие-то операции в Скале автоматически, то стоит внимательно посмотреть на функциональность ESC.

Итак. Регистрируем сервис ЦБ командой Add Service Reference. Создаем новое Workflow, которое будет обновлять курсы. Добавляем канал для оповещения по e-mail. Создаем новый Business Event Type, сразу привязывая его к созданному ранее Workflow. Добавляем расписание – Scheduled Events.

Во всей этой цепочке самое сложное – Workflow. Сложность возникает из-за того, что сделать все нужные преобразования в визуальном режиме не получится, приходится разбираться с веселыми языком XSLT. В качестве основы можете использовать мой вариант (Огромное спасибо Дмитрию Осипову за помощь). Он сделан для версии iScala 2.3 SR1. В архиве копия каталога Workflow, плюс шаблоны e-mail.

ExchRates

  • Date Request / Get Latest Date – запрос последней даты, на которую объявлены курсы, метод GetLatestDate
  • Request Rates / Get Exchange Rates – запрос курсов, метод GetCursOnDateXML
  • Update Rates / Exchange Rates In – вычисление производных курсов и обновление курсов
  • Send OK / Send Fail – оповещение пользователей об успехе / ошибке

SQL Server Integration services

Предположим, что ESC у вас нет. Тогда есть неплохой вариант – в качестве бесплатного приложения к MS SQL мы получаем службу Integration Services. С помощью этих сервисов можно получить данные с сайта ЦБ и записать в БД. Минус этого решение в том, что придется самому писать данные в таблицу курсов минуя Скалу. Сам я такой вариант не делал, но пример решения, которое подойдет в качестве основы, можно посмотреть здесь.

SQL Server

Следующий вариант – нет ESC, нет Integration Services. Это тоже не тупик. В TSQL есть возможность создавать объекты OLE Automation. Эта возможность отключена по умолчанию, т.к. считается потенциально опасной, для включения нужно выполнить следующий скрипт:


sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO

В качестве такого объекта можно использовать MSXML2.DOMDocument, с помощью него можно скачать XML с курсами с того же сайта ЦБ, разобрать его и сохранить курсы в БД. Такой вариант использовался у одного из клиентов, делалось решение на основе этой дискуссии на sql.ru.

суббота, ноября 28, 2009

iScala Database Structure

Разбирался с созданием веб-приложений на основе Google App Engine. В качестве примера сделал простую страничку, показывающую структуру базы данных Scala. Получилось достаточно забавно, так что я решил все это выложить. Расположено приложение по адресу http://db.apicosoft.ru/ .
Была еще идея добавить возможность оставлять комментарии во всех разделах(объяснение для чего нужен объект, примеры кода запросов...), но сразу решил не делать, посмотрим нужно ли вообще это. Тем более, что есть куча людей, считающих такого рода информацию чуть ли не секретной - злобный пользователь прознает и залезет куда не надо.
UPDATE 24.12.2009: Оказалось, что я не совсем правильно скачал структуру (считал, что актуальная информация в ScalaSystem.mdb, а нужно было брать из ScaConvertDB.mdb). Поправил. Заодно обнаружил дополнительную информацию в ScaConvertDB. Как вам, например, такой комментарий к полю SY24001:

Code Type Identifies the type of code: 
Code - Description (Module(s) : Length) 

A1 - Communication channel (SY : 2) 
A2 - IBAN (SY : 2) 
A3 - Common address (SY : 2) 
A4 - Common address sub-type (SY : 2) 
A5 - Address entries (SY : 2) 
AA - Journal codes (GL : 6) 
AB - Cash books (GL : 6) 
AT - Tier (GL : 2) 
AX - Cash office (GL : 8) 
AY - Reason codes (GL : 2) 
AZ - Compound Category (GL : 2) 

A0 - Asset group (GL : 10) 
AF - Category A (GL : 4) 
AG - Category B (GL : 4) 
AH - Location (GL : 15) 
AI - Engineer (GL : 25) 
AJ - Disposal code (GL : 4) 
A6 - User defined field 1 (GL : 15) 
A7 - User defined field 2 (GL : 10) 
A8 - User defined field 3 (GL : 10) 
A9 - User defined field 4 (GL : 5) 
AC - Insurance company (GL : 25) 
AD - Insurance category (GL : 20) 
AE - Business transaction code (GL : 3) 
AK - Hospitality simulation transactions (GL : 2) 

BA - Post codes (SL : 10) 
BB - Categories (SL : 4) 
BC - Districts (SL : 2) 
BD - Advertising areas (SL : 2) 
BE - Area codes (SL : 4) 
BF - Trade codes (SL : 5) 
BG - Discount codes (SL : 2) 
BH - Accrual codes (SL : 2) 
BI - Commission codes (SL : 2) 
BJ - Bank codes (SL : 10) 
BK - Salesmen (SL/ST/PR : 3) 
BL - Field engineers (SL : 4) 
BM - Country codes (SL : 3) 
BN - Statistical codes (SC : 13) 
BO - Export codes (SL : 1) 
BP - Payment codes (SL : 2) 
BQ - Accounting code customer (SL : 2) 
BT - Billing terms (SL/PL : 4) 
BS - Document type (SL/PL : 3) 
BV - Jurisdiction code (SY/SL/PL : 2) 

CA - Post codes (PL : 10) 
CB - Categories (PL : 4) 
CC - Country codes (PL : 3) 
CD - Bank codes (PL : 10) 
CE - Sales tax codes (PL : 2) 
CF - Central bank codes (PL : 2) 
CG - Authorization codes (PL : 5) 
CH - Organization codes (PL : 1) 
CI - Accounting code supplier (PL : 2) 
CJ - Supplier type (PL : 1) 

DA - Purchaser (MP/PC/SC : 3) 
DC - Document codes (SY : 1) 

EA - Skill codes (HR/SM : 3) 
EB - Engineer categories (HR/SM : 4) 
EC - Price codes (HR/SM/PR : 2) 
ED - Order status (SM : 2) 
EE - Weighted priorities (OR/PR/SM : 1) 
EF - Order priorities (OR/PR/SM : 1) 
EG - Analysis codes (SM : 15) 
EH - Issue status (SM : 6) 
EI - Return status (SM : 6) 
EJ - Work schedule codes (HR/SM/PR : 6) 
E1 - Error code (SM : 8) (Code EK replaced with E1) 
EL - Error type (SM : 2) 
EM - Error category (SM : 4) 
EN - Status (SM : 2) 
EO - Note category (SM : 2) 
EP - Key word (SM : 15) 
EQ - Note code (SM : 2) 
ER - Price calculation profile (SM : 10) 
EX - Service order accounting codes order (SM : 2) 
EY - Service order accounting codes activ (SM : 2) 
EZ - Service contract accounting codes (SM : 2 
E0 - Type of days (SM : 1) 
E2 - Customer priority codes (SL : 1) 

F0 - Accounting code PUR (AM : 2) 
F1 - Accounting code TAX (AM : 2) 
F2 - Accounting code PLA (AM : 2) 
F3 - Accounting code SAL (AM : 2) 
F4 - Accounting code SCR (AM : 2) 
F5 - Accounting code REV (AM : 2) 
F6 - Accounting code ETX (AM : 2) 
F7 - Accounting code FUS (AM : 2) 
F8 - Accounting code ICT (AM : 2) 
F9 - Accounting code PLP (AM : 2) 
FA - Accounting code ACT (AM : 2) 
FB - Accounting code OLD (AM : 2) 
FC - Accounting code TRA (AM : 2) 
FD - Accounting code STO (AM : 2) 
FE - Accounting code REA (AM : 2) 
FF - Accounting code SFA (AM : 2) 
(FF - FP - Reserved for Asset Transaction Accounting codes) 
(F* - Reserved for Asset Management module) 

IA - Query queues (SC : 1) 
IB - Product groups (SC : 4) 
IC - Article status (SC : 1) 
ID - Discount codes (SC : 2) 
IE - Accounting codes (SC : 2) 
IF - Maintenance codes (SC : 1) 
IG - Service levels (SC : 1) 
IH - Service priority (SC : 1) 
II - Product categories (SC : 10) 
IJ - Budget types (SC : 2) 
IK - Extended product group (SC : 20) 
IL - Price list (SC/PR/OR/PC : 2) 
IM - Batch status codes (SC : 1) 
IN - Cost types (SC : 2) 
IQ - User defined field 1 (SC : 10) 
IR - User defined field 2 (SC : 10) 
IS - User defined field 3 (SC : 8) 
IT - User defined field 4 (SC : 6) 
IU - User defined field 5 (SC : 4) 
IV - User defined field 6 (SC : 4) 
IW - User defined field 7 (SC : 2) 
IX - User defined field 8 (SC : 2) 
IY - User defined field 9 (SC : 2) 
IZ - User defined field 10 (SC : 2) 
I1 - Cycle counting reason (SC : 4) 
I2 - Storage type (SC : 1) 
I3 - Bin type (SC : 3) 
I4 - Bin location rule type (SC : 4) 

GA - Serial number Standard transaction types (SC : 1) 
GB - Serial number Incident Codes (SC : 4) 
GC - Serial number Priority Codes (SC : 4) 
GD - Serial number Action Codes (SC : 4) 
GE - Serial number Status Codes (SC : 4) 
GH - QC Category (SC : 2) 
GF - Serial number User transaction types (SC : 3) 

HA - Cancellation code (OR : 4) 

MR - Customer request type (MA : 2) 

PA - Profession codes (PA : 4; HR/PR/SM : 6) 
PB - Education codes (PA : ) 
PC - Categories (PA : ) 
PD - Departments (PA : 5; HR/PR/SM : 15) 
PE - Community codes 1 (PA : 2) 
PF - Community codes 2 (PA : 2) 
PG - Community codes 3 (PA : 2) 
PH - Work places (PA : 5) 
PI - Person categories (PA : 1) 
PJ - Labour agreement areas (PA : 5) 
PK - Statistical codes 1 (PA : 1) 
PL - Statistical codes 2 (PA : 1) 
PM - Statistical codes 3 (PA : 1) 
PN - Statistical codes 4 (PA : 1) 
PO - Statistical codes 5 (PA : 1) 
PP - Statistical codes 6 (PA : 1) 
PQ - Vacation codes (PA : 4) 
PV - History categories (PA : 2) 

QA - Direct invoicing (DI : 2) 

R0 - User Field 1 (PR : 20) 
R1 - User Field 2 (PR : 10) 
R2 - User Field 3 (PR : 10) 
R3 - User Field 4 (PR : 8) 
R4 - User Field 5 (PR : 8) 
R5 - User Field 6 (PR : 4) 
R6 - User Field 7 (PR : 4) 
R7 - User Field 8 (PR : 2) 
R8 - User Field 9 (PR : 2) 
R9 - User Field 10 (PR : 1) 
RA - User DB Defined 1 (PR : 1-35) 
RB - User DB Defined 2 (PR : 1-35) 
RC - User DB Defined 3 (PR : 1-35) 
RD - User DB Defined 4 (PR : 1-35) 
RE - User DB Defined 5 (PR : 1-35) 
RF - User DB Defined 6 (PR : 1-35) 
RG - User DB Defined 7 (PR : 1-35) 
RH - User DB Defined 8 (PR : 1-35) 
RI - User DB Defined 9 (PR : 1-35) 
RJ - User DB Defined 10 (PR : 1-35) 
RK - (reserved) (PR : ) 
RL - Project category (PR : 4) 
RM - Project type (PR : 2) 
RN - Project status (PR : 1) (not used) 
RO - Project report codes (PR : 8) 
RP - Project budget codes (PR : 2) 
RQ - Project Text Group Description (PR : 1) 
RR - Project User Def Desc (PR : 1) 
RS - Accounting Codes Project (PR : 2) 
RT - Accounting codes Activity (PR : 2) 
RU - Activity cost category (PR : 1) 
RV - Activity gategory (PR : 10) 
RW - Project discount code (PR : 2) 
RX - Activity discount code (PR : 2) 
RY - Invoice sort code (PR : 2) 
RZ - (reserved) (PR : ) 

S* - (reserved) (PR : ) 
SB - IBAN Bank types (SY : 2) 
SE - IBAN Account entry (SY : 1) 
SF - IBAN Section filling (SY : 1) 
SG - IBAN Layout groups (SY : 1) 
ST - IBAN Section type (SY : 1) 
SV - IBAN Validation rule (SY : 3) 

TD - District codes (PL : 10) 

SA - Layout codes (GL : 11) 

WT - Withholding tax codes (PL : 4) 

X0 - Printer groups (SY : 2) 

Y0 - Header batch field 1 (SC/PC/OR/MP : 1) 
Y1 - Header batch field 2 (SC/PC/OR/MP : 1) 
Y2 - Header batch field 3 (SC/PC/OR/MP : 1) 
Y3 - Header batch field 4 (SC/PC/OR/MP : 1) 
Y4 - Header batch field 5 (SC/PC/OR/MP : 1) 
Y5 - Header batch field 6 (SC/PC/OR/MP : 1) 
Y6 - Header batch field 7 (SC/PC/OR/MP : 1) 
Y7 - Header batch field 8 (SC/PC/OR/MP : 1) 
Y8 - Header batch field 9 (SC/PC/OR/MP : 1) 
Y9 - Header batch field 10 (SC/PC/OR/MP : 1) 
YA - Batch user field 1 (SC/PC/OR/MP : 20) 
YB - Batch user field 2 (SC/PC/OR/MP : 10) 
YC - Batch user field 3 (SC/PC/OR/MP : 10) 
YD - Batch user field 4 (SC/PC/OR/MP : 8) 
YE - Batch user field 5 (SC/PC/OR/MP : 8) 
YF - Batch user field 6 (SC/PC/OR/MP : 4) 
YG - Batch user field 7 (SC/PC/OR/MP : 4) 
YH - Batch user field 8 (SC/PC/OR/MP : 2) 
YI - Batch user field 9 (SC/PC/OR/MP : 2) 
YJ - Batch user field 10 (SC/PC/OR/MP : 1) 

Z2 - Operation Code (SY/SL/PL : 10) 
Z3 - Cust/Supp Activity (SY/SL/PL : 10) 
Z4 - Invoice Type (SY/SL/PL : 10) 
Z5 - Brazilian Regions (SY/SL/PL : 10) 
Z6 - City Codes (SY/SL/PL : 10) 
Z7 - State Codes (SY/SL/PL : 10) 
Z8 - (reserved) 
Z9 - Taxable Situation (SY/SL/PL : 10) 
ZA - Type of Legal Entities (SY/SL/PL : 10) 
ZB - Service Codes (SY/SL/PL : 10) 
ZC - Tax Accounting Codes (SY/SL/PL : 1) 

V* - Reserved for VBA projects (all codes starting with V) 
W* - Reserved for VBA projects (all codes starting with W except for WT) 

понедельник, июля 20, 2009

SET NOCOUNT ON

В очередной раз наступил на эти грабли и решил написать – начинайте написание любой процедуры, триггера, просто длинного запроса со строки:


SET NOCOUNT ON


Без этой строки вы реально можете получить проблемы, например, в отчетах, быстрых поисках (если пишете запрос руками и там более одной конструкции), в стандартной функциональности (в случае использования триггеров).
Вот, что написано про эту конструкцию в документации:
Если значение инструкции SET NOCOUNT равно ON, то количество строк не возвращается. Если значение инструкции SET NOCOUNT равно OFF, то количество строк возвращается.
Функция @@ROWCOUNT обновляется, даже если значение SET NOCOUNT равно ON.
Инструкция SET NOCOUNT ON запрещает всем инструкциям хранимой процедуры отправлять клиенту сообщения DONE_IN_PROC. Для хранимых процедур с несколькими инструкциями, не возвращающих большое количество фактических данных, установка в инструкции SET NOCOUNT значения ON может значительно повысить производительность за счет существенного снижения объема сетевого трафика.
Инструкция SET NOCOUNT устанавливается во время выполнения, а не на этапе синтаксического анализа.

пятница, июля 17, 2009

MS SQL Profiler

Profiler – очень мощный инструмент трассировки, упрощающий отладку новых процедур, решение проблем с доступом к данным, оптимизацию быстродействия и т.д.
Термины, связанные с трассировкой:

  • Events/События – набор действий, происходящих на сервере, например, запуск хранимой процедуры, сходные события объединены в категории событий
  • Data columns/Поля – каждое конкретное событие имеет набор свойств
  • Filters/Фильтры – позволяют выбирать только нужные события
Сама программа обладает несколько архаичным интерфейсом. В результате использование ее не столь очевидно.
Пользоваться трассировщиком по умолчанию может пользователь SA и члены роли SYSADMINS. Начиная с версии SQL Server 2005 можно делегировать эти права любому пользователю:
1: -- разрешаем трассировку для LoginID
2: USE master
3: GRANT ALTER TRACE TO LoginID
4: GO
5: 
6: -- запрещаем трассировку для LoginID
7: USE master
8: REVOKE ALTER TRACE TO LoginID
9: GO
10: 


Для установки профайлера на рабочую станцию нужно воспользоваться дистрибутивом MS SQL, выбрав соответствующую опцию. Никаких дополнительных лицензий для этого не требуется.
Profiler после запуска начинает собирать информацию в соответствии с выбранными событиями, полями и фильтрами. Все это делается в памяти компьютера, на котором он запущен. Поэтому запускать длительную трассировку на основном сервере не лучшая идея, лучше сделать это с рабочей станции.
Запускаем трассировку:
  1. Запускаем Profiler
  2. File –> New Trace
  3. Connect to server – стандартное окно выбора сервера (трассировать можно базу данных или аналитические сервисы)
  4. Trace Properties – окно настройки трассировки. Позволяет выбрать события, поля событий и фильтры. Стоит обратить внимание на поле “Use the template”. Шаблон в данном случае – это набор предопределенных для характерных ситуаций настроек трассировки. Можно добавить свои шаблоны.
  5. Жмем кнопку Run
Появляется основное окно трассировки. Оно разделено на две горизонтальные панели. В верхней панели выводятся захваченные события, каждой строке соответствует одно событие. В нижней панели выводится содержимое поля TextData выбранной строки верхней панели.
Стандартный набор команд позволяет поставить на паузу, остановить, запустить трассировку. Результаты трассировки можно сохранить (File –> Save).
Трассировка реально помогает в понимании как работает сервер баз данных, облегчает поиск проблем. Для эффективного использования, конечно, нужно понимать значение событий и полей, в связи с этим хочу обратить внимание, что если в окне Trace Properties навести курсор на поле либо на событие, то внизу окна появится краткое описание события и поля.
В завершении несколько фактов о Profiler:
  • Начиная с версии MS SQL 2005 появилось новое событие Deadlock Graph. Оно значительно упрощает поиск взаимных блокировок, т.к. в графическом виде показывает суть конфликта.
  • Профайлер позволяет не только захватывать события, но и воспроизводить их обратно на сервере. Так что его можно использовать как простейшее средство стрессового тестирования.
  • Трассировку можно запускать программным способом. Причем в профайлере есть команда, облегчающая создания скрипта запуска трассировки. Для этого нужно просто запустить профайлер, создать новую трассировку, выставив все необходимы параметры. После этого запустите команду File –> Export –> Script Trace Definition –> For SQL Server… Вот для примера скрипт, созданный на основе стандартного шаблона:

1: /****************************************************/
2: /* Created by: SQL Server 2008 Profiler             */
3: /* Date: 17/07/2009  16:36:59         */
4: /****************************************************/
5: 
6: 
7: -- Create a Queue
8: declare @rc int
9: declare @TraceID int
10: declare @maxfilesize bigint
11: declare @DateTime datetime
12: 
13: set @DateTime = '2009-07-20 18:00:00.000'
14: set @maxfilesize = 5
15: 
16: -- Please replace the text InsertFileNameHere, with an appropriate
17: -- filename prefixed by a path, e.g., c:\MyFolder\MyTrace. The .trc extension
18: -- will be appended to the filename automatically. If you are writing from
19: -- remote server to local drive, please use UNC path and make sure server has
20: -- write access to your network share
21: 
22: exec @rc = sp_trace_create @TraceID output, 0, N'InsertFileNameHere', @maxfilesize, @Datetime
23: if (@rc != 0) goto error
24: 
25: -- Client side File and Table cannot be scripted
26: 
27: -- Set the events
28: declare @on bit
29: set @on = 1
30: exec sp_trace_setevent @TraceID, 14, 1, @on
31: exec sp_trace_setevent @TraceID, 14, 9, @on
32: exec sp_trace_setevent @TraceID, 14, 6, @on
33: exec sp_trace_setevent @TraceID, 14, 10, @on
34: exec sp_trace_setevent @TraceID, 14, 14, @on
35: exec sp_trace_setevent @TraceID, 14, 11, @on
36: exec sp_trace_setevent @TraceID, 14, 12, @on
37: exec sp_trace_setevent @TraceID, 15, 15, @on
38: exec sp_trace_setevent @TraceID, 15, 16, @on
39: exec sp_trace_setevent @TraceID, 15, 9, @on
40: exec sp_trace_setevent @TraceID, 15, 17, @on
41: exec sp_trace_setevent @TraceID, 15, 6, @on
42: exec sp_trace_setevent @TraceID, 15, 10, @on
43: exec sp_trace_setevent @TraceID, 15, 14, @on
44: exec sp_trace_setevent @TraceID, 15, 18, @on
45: exec sp_trace_setevent @TraceID, 15, 11, @on
46: exec sp_trace_setevent @TraceID, 15, 12, @on
47: exec sp_trace_setevent @TraceID, 15, 13, @on
48: exec sp_trace_setevent @TraceID, 17, 1, @on
49: exec sp_trace_setevent @TraceID, 17, 9, @on
50: exec sp_trace_setevent @TraceID, 17, 6, @on
51: exec sp_trace_setevent @TraceID, 17, 10, @on
52: exec sp_trace_setevent @TraceID, 17, 14, @on
53: exec sp_trace_setevent @TraceID, 17, 11, @on
54: exec sp_trace_setevent @TraceID, 17, 12, @on
55: exec sp_trace_setevent @TraceID, 10, 15, @on
56: exec sp_trace_setevent @TraceID, 10, 16, @on
57: exec sp_trace_setevent @TraceID, 10, 9, @on
58: exec sp_trace_setevent @TraceID, 10, 17, @on
59: exec sp_trace_setevent @TraceID, 10, 2, @on
60: exec sp_trace_setevent @TraceID, 10, 10, @on
61: exec sp_trace_setevent @TraceID, 10, 18, @on
62: exec sp_trace_setevent @TraceID, 10, 11, @on
63: exec sp_trace_setevent @TraceID, 10, 12, @on
64: exec sp_trace_setevent @TraceID, 10, 13, @on
65: exec sp_trace_setevent @TraceID, 10, 6, @on
66: exec sp_trace_setevent @TraceID, 10, 14, @on
67: exec sp_trace_setevent @TraceID, 12, 15, @on
68: exec sp_trace_setevent @TraceID, 12, 16, @on
69: exec sp_trace_setevent @TraceID, 12, 1, @on
70: exec sp_trace_setevent @TraceID, 12, 9, @on
71: exec sp_trace_setevent @TraceID, 12, 17, @on
72: exec sp_trace_setevent @TraceID, 12, 6, @on
73: exec sp_trace_setevent @TraceID, 12, 10, @on
74: exec sp_trace_setevent @TraceID, 12, 14, @on
75: exec sp_trace_setevent @TraceID, 12, 18, @on
76: exec sp_trace_setevent @TraceID, 12, 11, @on
77: exec sp_trace_setevent @TraceID, 12, 12, @on
78: exec sp_trace_setevent @TraceID, 12, 13, @on
79: exec sp_trace_setevent @TraceID, 13, 1, @on
80: exec sp_trace_setevent @TraceID, 13, 9, @on
81: exec sp_trace_setevent @TraceID, 13, 6, @on
82: exec sp_trace_setevent @TraceID, 13, 10, @on
83: exec sp_trace_setevent @TraceID, 13, 14, @on
84: exec sp_trace_setevent @TraceID, 13, 11, @on
85: exec sp_trace_setevent @TraceID, 13, 12, @on
86: 
87: 
88: -- Set the Filters
89: declare @intfilter int
90: declare @bigintfilter bigint
91: 
92: exec sp_trace_setfilter @TraceID, 6, 0, 6, N'User1'
93: exec sp_trace_setfilter @TraceID, 10, 0, 7, N'SQL Server Profiler - b384f0b7-6852-4661-86de-2da85ca97fdf'
94: -- Set the trace status to start
95: exec sp_trace_setstatus @TraceID, 1
96: 
97: -- display trace id for future references
98: select TraceID=@TraceID
99: goto finish
100: 
101: error: 
102: select ErrorCode=@rc
103: 
104: finish: 
105: go
106: 

суббота, июля 11, 2009

EXECUTE AS

Предположим, что мы делаем отчет для пользователя. Данные выбираются из базы данных с помощью хранимой процедуры, а выводятся, например, в Excel. В этом случае приходится давать пользователю прямой доступ к базе. И тут сразу возникает вопрос – как дать доступ только туда, куда нужно.

Варианты следующие:

  1. Выбираем нужные таблицы и даем пользователю право читать их. Неудобно то, что все нужно будет повторять для каждого отчета и пользователя. Введение специальных ролей тоже не особо поможет, т.к. для каждого отчета набор таблиц обычно разный, плюс со временем может меняться как сам набор таблиц, так и пользователи, которым разрешен запуск отчета.
  2. Включаем пользователя в роль db_datareader. В этом случае проблем с администрированием почти никаких, но пользователь будет иметь возможность читать все таблицы базы данных. В большинстве случаев политика безопасности предприятия не позволяет делать так.
  3. Дать пользователю только право запускать хранимую процедуру, а уже внутри процедуры переключить контекст с помощью конструкции EXECUTE AS. В этом случае пользователь не будет иметь никаких избыточных прав, а администрирование сводится только к выдаче прав на конкретную процедуру.

Пример процедуры, реализующей последний вариант:

  1: USE iScalaDB
  2: 
  3: -- создаем новый логин
  4: CREATE LOGIN ReportUserLogin WITH PASSWORD='ERFss$#45%$'
  5: GO
  6: 
  7: -- создаем пользователя, на которого будем переключать контекст
  8: CREATE USER ReportUser FOR LOGIN ReportUserLogin
  9: GO
 10: 
 11: -- даем вспомогательному пользователю право читать всю базу данных
 12: EXEC sp_addrolemember 'db_datareader','ReportUser'
 13: GO
 14: 
 15: -- создаем проверочную процедру
 16: CREATE PROCEDURE dbo.TestExecuteAS
 17: WITH EXECUTE AS 'ReportUser'
 18: AS
 19: BEGIN
 20:     SET NOCOUNT ON
 21: 
 22:     SELECT *
 23:     FROM GL060108
 24: END
 25: GO
 26: 


Конструкция EXECUTE AS появилась в MS SQL2005, в более ранних версиях была команда SETUSER, но она имела ряд ограничений, которые не позволяли использовать ее в нашем сценарии.

пятница, февраля 27, 2009

Сумма прописью

Ситуация: вы настроили новую валюту и печатаете счет в этой валюте. Обратите внимание на поле, где выводится сумма прописью, с большой вероятностью валюта там не совпадет с той, что вы настроили. Где же находится связь между алгоритмом  вывода суммы прописью и конкретной валютой?

Запускаем iScala Administration Console. Выбираем: Языки - Строки LAN файлов - GEN - RUS - SY - Numbers. Именно в этом файле все и хранится, спасибо Владимиру Певзнеру за подробный комментарий:

;0001        *** File created by Scala CIS (Moscow) 1 April 1998 ***    |
;0002              Adjusted VP/Jul 1999 by Vladimir Pevzner                  |
;0003     Это специальный LAN файл для печати чисел прописью по-русски.      |
;0004 Файл содержит строки постоянной длины (всегда ровно 80 символов,       |
;0005 включая 2 символа для КОНЦА СТРОКИ). Первый символ каждой строки должен|
;0006 быть либо ' '(пробел) либо ';'(точка с запятой).                       |
;0007     Точка с запятой в первой позиции означает, что данная строка явля- |
;0008 ется комментарием. Число в позициях 2-5 означает номер строки. Програм-|
;0009 ма его не использует, однако оно полезно при корректировке данного или |
;0010 подготовке новых файлов, поскольку оно входит в формулы. Строки, испо- |
;0011 льзуемые программой содержат пробел в первой позиции.                  |
;0012                                                                        |
;0013     Приведенные ниже строки содержат БЛОК ПАРАМЕТРОВ (либо 1 символ в  |
;0014 позициях 7-10, либо 3 числа в позициях 7-8, 10 и 12-15, остальная ин-  |
;0015 фармация служит комментарием) :                                        |
;0016                                                                        |
 0017 0005      Количество валют                                             |
;0018                                                                        |
;0019     Ниже приведены параметры каждой валюты. Первый параметр в строке   |
;0020 показывает количество знаков после запятой. Оно может быть положитель- |
;0021 ным, нулевым или отрицательным (например, -3, если учет ведется в тыся-|
;0022 чах денежных единиц). Второй параметр указывает, нужно ли показывать   |
;0023 прописью знаки после запятой (1-да, 0-нет). Третий парамер показывает  |
;0024 номер строки, с которой начинается блок данных для указанной валюты.   |
;0025                                                                        |
 0026 02,0,0152  Для валюты   № 1                                            |
 0027 02,1,0162  Для валюты   № 2                                            |
 0028 02,0,0152  Для валюты   № 3                                            |
 0029 02,0,0152  Для валюты   № 4                                            |
 0030 02,0,0192                                                              |
;0031 <<зарезервировано для валюты № 6>>                                     |
;0032 <<зарезервировано для валюты № 7>>                                     |
;0033 <<зарезервировано для валюты № 8>>                                     |
;0034 <<зарезервировано для валюты № 9>>                                     |
;0035 <<зарезервировано для валюты № 10>>                                    |
;0036                                                                        |
 0037 0213      Номер первой строки блока формул                             |
;0038                                                                        |
;0039     Приведенные ниже строки содержат БЛОК ДАННЫХ (действительные данные|
;0040 помещены в кавычки, остальная информация служит комментарием) :        |

Думаю, что теперь разобраться не проблема. Редактируем файл и проверяем.