- 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
                                 
        
Все, кто после меня - педерасты и хуегасы.
btw, странная мешанина из drop table (прямой ddl в процедуре-то?) и синтаксис select ... into just_deleted_table (так можно?)
что-то не так в вашем датском королевстве
это MS SQL?
У меня горизонтальный скролл отбил все желание ;(
Описалово надо подправить.
каквирнёцо, нараз и падправим
Полагаю, вопрос риторический. :)
Да, таблица создастся со структурой селекта (только типы данных, никаких констрейнтов, индексов и т.п.). Вообще, это - грязный хак. Использовать в крайнем случае.
> что-то не так в вашем датском королевстве
Проекту, скорее всего, овер 10 лет, начиналось всё на МС СКЛ 2000, гениальный рахитектор того времени решил запихнуть всю бизнес логику в СУБД (ибо перформанс) и никто не хочет это говно переписывать.
> это MS SQL?
Такую простыню можно и на PL/SQL состряпать.
именно об этом я и спросил, что в MSSQL у вас что-то не то
select ... into unknown_name - это полный пиздец
вместо ошибки, что такой переменной нет, он берёт и создает таблицу с этим именем?
что за ад
в оракле есть конструкция
create table foobar as select ... - всё понятно, конфликтов с переменными нет
>именно об этом я и спросил, что в MSSQL у вас что-то не то
Ну я же сказал, что SELECT ... INTO - это грязный хак, и его использование - это какбэ сигнал, что что-то пошло не так.
> select ... into unknown_name - это полный пиздец
ммм... почему?
Такая конструкция работает ТОЛЬКО на создание новой таблицы и всё.
> вместо ошибки, что такой переменной нет, он берёт и создает таблицу с этим именем?
С переменными так нельзя. Если хочешь присвоить какое-то поле в переменную, то делаешь SELECT @myVariable = someField FROM ... .
> что за ад
Ну тут главное помнить, что переменные должны начинаться с пёсика и всё будет ок.
В говнокоде ад в бизнес логике, завёрнутую в простыню.
просто для справки, в MSSQL можно сделать вот так? (сорри, sqlfiddle сегодня не работает...)
Вот так нельзя. Т.е. возьми поля того типа, что вооон в той таблице. Удобно, конечно. Но, как-то без этого можно жить.
> тип 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;
Как-то так. Может оно и выглядит как через одно место, но функции свои выполняет и дискомфорта не испытываешь.
ну, в частности, какой результат имеет fetch из курсора?
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;
...
Специально усложняем использование курсора, чтоб не повадно было юзать :)
но... ведь... курсор...
кстати, в мсдновском примере можно было бы вообще без курсоров обойтись :-P
http://www.sqlfiddle.com/#!4/40a7ae/2
* смотреть Plaintext output
Угу, курсор - это вообще крайняя мера.
В основном, я к нему прибегал только когда надо что-то по метаданным сконструировать хитрое с динамическим SQL.
Вот кому нельзя работать на атомных электростанциях...
bart, +1