- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
CREATE PROCEDURE DEPTORS_EURO AS -- Но сначала отключу ТРИГГЕРА
ALTER TABLE DEPTORS_REFERENCE DISABLE TRIGGER Tr_for_DEPTORS_REFERENCE
ALTER TABLE DEPTORS_DOC_EURO DISABLE TRIGGER Tr_for_DEPTORS_DOC_EURO
ALTER TABLE DEPTORS_Remander DISABLE TRIGGER Tr_for_DEPTORS_REMANDER
ALTER TABLE DEPTORS_Payment DISABLE TRIGGER Tr_for_DEPTORS_Payment -- Создаю документ DEPTORS_DOC_EURO_old
Она будет нужна для поиска оплативших долги АК и появившихся новых */
IF EXISTS(SELECT name -- Удаляю, если существует в БД
FROM sysobjects WHERE name = N'DEPTORS_DOC_EURO_old' AND type = 'U') DROP TABLE DEPTORS_DOC_EURO_old
SELECT * INTO DEPTORS_DOC_EURO_old -- Это DEPTORS за предыдущий месяц
FROM DEPTORS_DOC_EURO -- После копирования данных - уничтожим DEPTORS_DOC_EURO
DELETE DEPTORS_DOC_EURO -- Т.О. по FK-PK обнуляютя таблицы
DELETE FROM STATEMENT_UKRSTA WHERE mvt_date =
(SELECT DISTINCT LATEST__DATE -- выбираю дату
FROM STATEMENT_UKRSTA , CALENDAR_BILL_DATE WHERE
DATEPART(mm,FLIGHT_PERIOD) = DATEPART(mm, (SELECT DATEADD(mm,-1, MAX(stac_date)) FROM STATEMENT_UKRSTA WHERE type = 'FB')) and
DATEPART(yy,FLIGHT_PERIOD) = DATEPART(yy, (SELECT DATEADD(mm,-1, MAX(stac_date)) FROM STATEMENT_UKRSTA WHERE type = 'FB')) and
type = 'FB') -- Удаляю из таблицы STATEMENT_UKRSTA все АК, которые не имеют долгов
DELETE FROM STATEMENT_UKRSTA WHERE corr IN (SELECT corr FROM STATEMENT_UKRSTA a GROUP BY a.corr HAVING Sum(a.saldo) <= 0 )
-- Создаю псевдовременную таблицу по выборке DEPTORS_REFERENCE_Vrem
IF EXISTS(SELECT name -- Удаляю, если существует в БД
FROM sysobjects WHERE name = N'DEPTORS_REFERENCE_Vrem' AND type = 'U') DROP TABLE DEPTORS_REFERENCE_Vrem
SELECT corr, type, SUBSTRING(reference,1,6) AS Account, Sum(saldo) AS Saldo INTO DEPTORS_REFERENCE_Vrem FROM STATEMENT_UKRSTA GROUP BY corr, type, reference HAVING SUM(saldo) > 0
-- Т.К. FK-PK то сначала внесем User_Ref всех должников в DEPTORS_DOC_EURO
IF EXISTS(SELECT name -- Удаляю, если существует в БД
FROM sysobjects WHERE name = N'USER_REF' AND type = 'U')
DROP TABLE USER_REF
SELECT DISTINCT corr INTO USER_REF FROM DEPTORS_REFERENCE_Vrem
INSERT INTO DEPTORS_DOC_EURO SELECT User_Ref=a.corr,DEBT_AMOUNT=Null,Name= Null,Country=Null,Code_ICAO=Null,Final_Date=Null,Period_of_Dept=Null,Saldo_D_Facte=0,Saldo_D_Ure=0 FROM USER_REF a
DROP TABLE USER_REF -- Заполняю таблицу DEPTORS_REFERENCE (User_Ref уже есть - поэтому позволит внести)
INSERT INTO DEPTORS_REFERENCE SELECT User_Ref=a.corr,reference=a.Account,type=a.type,Old_Saldo=a.Saldo,Saldo_D_Facte =0,Saldo_D_Ure=0 -- первично
FROM DEPTORS_REFERENCE_Vrem a -- Удалим псевдовременную таблицу DEPTORS_REFERENCE_Vrem
DROP TABLE DEPTORS_REFERENCE_Vrem -- Корректирую счета (Выставлено - Оплачено)
IF EXISTS(SELECT name -- Удаляю, если существует в БД
FROM sysobjects WHERE name = N'Vrem_Stat_Negativ_Saldo' AND type = 'U') DROP TABLE Vrem_Stat_Negativ_Saldo
SELECT corr, type, SUBSTRING(reference,1,6) AS Account, Sum(saldo) AS Saldo INTO Vrem_Stat_Negativ_Saldo FROM STATEMENT_UKRSTA GROUP BY corr, type, reference HAVING SUM(saldo) < 0 -- Сравниваю две таблицы (DEPTORS_REFERENCE и Vrem_Stat_Negativ_Saldo)
UPDATE a SET Old_Saldo = a.Old_Saldo + b.Saldo FROM DEPTORS_REFERENCE a INNER JOIN Vrem_Stat_Negativ_Saldo b ON a.User_Ref = b.corr and a.reference = b.Account
DROP TABLE Vrem_Stat_Negativ_Saldo -- Создаю новый документ DEPTORS_DOC_EURO
IF EXISTS(SELECT name -- Удаляю, если существует в БД
FROM sysobjects WHERE name = N'Vrem_DEPTORS_DOC_EURO' AND type = 'U') DROP TABLE Vrem_DEPTORS_DOC_EURO
SELECT User_Ref, SUM(Old_Saldo) AS Old_Saldo,SUM(Saldo_D_Facte) AS Saldo_D_Facte,SUM(Saldo_D_Ure) AS Saldo_D_Ure
INTO Vrem_DEPTORS_DOC_EURO FROM DEPTORS_REFERENCE GROUP BY User_Ref
UPDATE b
SET
DEBT_AMOUNT = a.Old_Saldo, Saldo_D_Facte = a.Old_Saldo, Saldo_D_Ure = a.Old_Saldo FROM Vrem_DEPTORS_DOC_EURO a INNER JOIN DEPTORS_DOC_EURO b ON a.User_Ref = b.User_Ref
DROP TABLE Vrem_DEPTORS_DOC_EURO
UPDATE a SET Name= b.corr_name FROM DEPTORS_DOC_EURO a INNER JOIN STATEMENT_UKRSTA b
ON a.User_Ref = b.corr
UPDATE a SET Code_ICAO = ICAO_CODE FROM DEPTORS_DOC_EURO a INNER JOIN AIRCOMPANYS b
ON (a.User_Ref = b.CRCO_NUMBER) OR (a.User_Ref = b.CRCO3)
UPDATE a SET Country = c.FULL_NAME FROM DEPTORS_DOC_EURO a INNER JOIN AIRCOMPANYS b
ON (a.User_Ref = b.CRCO_NUMBER) OR (a.User_Ref = b.CRCO3)
INNER JOIN COUNTRYS c ON b.COUNTRY_ID = c.ID
IF EXISTS(SELECT name -- Удаляю, если существует в БД
FROM sysobjects WHERE name = N'DEPTORS_DOC_EURO_NewDolg' AND type = 'U')
DROP TABLE DEPTORS_DOC_EURO_NewDolg
SELECT * -- Делаю выборку в таблицу
INTO DEPTORS_DOC_EURO_NewDolg FROM DEPTORS_DOC_EURO
WHERE User_Ref Not IN (SELECT User_Ref FROM DEPTORS_DOC_EURO_old)
IF EXISTS(SELECT name -- Удаляю, если существует в БД
FROM sysobjects WHERE name = N'DEPTORS_DOC_EURO_OplatDolg' AND type = 'U')
DROP TABLE DEPTORS_DOC_EURO_OplatDolg
SELECT * -- Делаю выборку в таблицу
INTO DEPTORS_DOC_EURO_OplatDolg FROM DEPTORS_DOC_EURO_old
WHERE User_Ref Not IN (SELECT User_Ref FROM DEPTORS_DOC_EURO)
ALTER TABLE DEPTORS_REFERENCE ENABLE TRIGGER Tr_for_DEPTORS_REFERENCE
ALTER TABLE DEPTORS_DOC_EURO ENABLE TRIGGER Tr_for_DEPTORS_DOC_EURO
ALTER TABLE DEPTORS_Remander ENABLE TRIGGER Tr_for_DEPTORS_REMANDER
ALTER TABLE DEPTORS_Payment ENABLE TRIGGER Tr_for_DEPTORS_Payment
Konardo 24.02.2014 22:51 # −12
Все, кто после меня - педерасты и хуегасы.
defecate-plusplus 25.02.2014 08:06 # +2
btw, странная мешанина из drop table (прямой ddl в процедуре-то?) и синтаксис select ... into just_deleted_table (так можно?)
что-то не так в вашем датском королевстве
это MS SQL?
bormand 25.02.2014 08:37 # +1
У меня горизонтальный скролл отбил все желание ;(
guest 25.02.2014 08:40 # −2
guest 25.02.2014 12:34 # −1
DBdev 25.02.2014 12:43 # −1
Описалово надо подправить.
guest 25.02.2014 18:12 # −2
каквирнёцо, нараз и падправим
Bart 25.02.2014 11:31 # −2
Полагаю, вопрос риторический. :)
inkanus-gray 25.02.2014 11:44 # 0
DBdev 25.02.2014 12:41 # 0
Konardo 25.02.2014 11:45 # −4
DBdev 25.02.2014 12:39 # −1
Да, таблица создастся со структурой селекта (только типы данных, никаких констрейнтов, индексов и т.п.). Вообще, это - грязный хак. Использовать в крайнем случае.
> что-то не так в вашем датском королевстве
Проекту, скорее всего, овер 10 лет, начиналось всё на МС СКЛ 2000, гениальный рахитектор того времени решил запихнуть всю бизнес логику в СУБД (ибо перформанс) и никто не хочет это говно переписывать.
> это MS SQL?
Такую простыню можно и на PL/SQL состряпать.
defecate-plusplus 25.02.2014 12:56 # −1
именно об этом я и спросил, что в MSSQL у вас что-то не то
select ... into unknown_name - это полный пиздец
вместо ошибки, что такой переменной нет, он берёт и создает таблицу с этим именем?
что за ад
в оракле есть конструкция
create table foobar as select ... - всё понятно, конфликтов с переменными нет
DBdev 25.02.2014 14:41 # −1
>именно об этом я и спросил, что в MSSQL у вас что-то не то
Ну я же сказал, что SELECT ... INTO - это грязный хак, и его использование - это какбэ сигнал, что что-то пошло не так.
> select ... into unknown_name - это полный пиздец
ммм... почему?
Такая конструкция работает ТОЛЬКО на создание новой таблицы и всё.
> вместо ошибки, что такой переменной нет, он берёт и создает таблицу с этим именем?
С переменными так нельзя. Если хочешь присвоить какое-то поле в переменную, то делаешь SELECT @myVariable = someField FROM ... .
> что за ад
Ну тут главное помнить, что переменные должны начинаться с пёсика и всё будет ок.
В говнокоде ад в бизнес логике, завёрнутую в простыню.
defecate-plusplus 25.02.2014 15:08 # −1
просто для справки, в MSSQL можно сделать вот так? (сорри, sqlfiddle сегодня не работает...)
DBdev 25.02.2014 17:13 # −1
Вот так нельзя. Т.е. возьми поля того типа, что вооон в той таблице. Удобно, конечно. Но, как-то без этого можно жить.
> тип record с полями
Такого понятия нет. У тебя либо скалярная переменная либо табличного типа.
> select * into foo from footable where rownum = 1;
Просто пишем такой запрос и получаем таблицу foo со структурой как footable с данными по условию.
Скоуп видимости можно задавать решёточками перед именем таблицы:
foo - статическая таблица;
#foo - временная таблица (хранится в темпдб, удалится по окончанию сессии ) с локальной видимостью;
##foo - временная таблица с глобальной видимостью, доступна из других сессий.
> select id, name, born into bar from footable where rownum = 1;
Вместо этого объявляем отдельно переменных столько, сколько полей.
DECLARE @id number(10), @name varchar(255), @born datetime;
Записываем значения в переменные.
select @id = id, @name = name, @born = born from footable where rownum = 1;
Как-то так. Может оно и выглядит как через одно место, но функции свои выполняет и дискомфорта не испытываешь.
defecate-plusplus 25.02.2014 18:26 # −1
ну, в частности, какой результат имеет fetch из курсора?
DBdev 25.02.2014 18:58 # −1
http://technet.microsoft.com/en-us/library/ms180169(v=sql.105).aspx
Последний пример с вложенными курсорами.
...
FETCH NEXT FROM vendor_cursor
INTO @vendor_id, @vendor_name;
...
FETCH NEXT FROM product_cursor INTO @product;
...
Специально усложняем использование курсора, чтоб не повадно было юзать :)
defecate-plusplus 25.02.2014 19:11 # −1
но... ведь... курсор...
кстати, в мсдновском примере можно было бы вообще без курсоров обойтись :-P
defecate-plusplus 25.02.2014 20:14 # 0
http://www.sqlfiddle.com/#!4/40a7ae/2
* смотреть Plaintext output
DBdev 26.02.2014 16:21 # 0
Угу, курсор - это вообще крайняя мера.
В основном, я к нему прибегал только когда надо что-то по метаданным сконструировать хитрое с динамическим SQL.
Bart 25.02.2014 11:32 # +1
Вот кому нельзя работать на атомных электростанциях...
Stertor 25.02.2014 14:46 # −2
bart, +1