SQL вставка в не существует по нескольким результатам - PullRequest
3 голосов
/ 18 ноября 2011

У меня есть таблица плана, которая имеет отношение один ко многим с таблицей цен. (1 план может иметь много цен)

Однако проблема в том, что у меня есть другая таблица под названием «Стандартные цены», в которой хранятся имена всех цен (причина в том, что я хочу иметь возможность добавлять или удалять цены в любое время)

 Plan Table:
 ID int primary key,
 plan Name varchar(200),
 ...

 PriceTable:
 ID int primary key,
 PlanId int foreign key references plan(ID)
 PriceName ID foreign key standardprices(id)

 StandardPrices:
 ID int primary key,
 PriceName varchar(200),
 DefaultPrice money

Таким образом, всякий раз, когда создается план, он автоматически создает список всех цен в списке StandardPrice (со значениями по умолчанию).

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

Я использую хранимые процедуры и думал, что лучший способ сделать это - через SQL.

Когда создаются стандартные цены:

   begin      
   insert into StandardPrices (PriceName, Defaultprice)
       values (@priceName, @DefaultPrice)
   end

   begin
   //list all plans.
   //cross reference PriceTable to see if plan exists
   //if not insert priceplan with default value
   end

Я немного запутался, как я могу реализовать такую ​​команду sql?

Ответы [ 4 ]

3 голосов
/ 18 ноября 2011

Я думаю, это выглядит примерно так:

insert into PriceTable (PlanId, PriceName)
select PlanId, @priceName
from Plan
where not exists 
  (select null from PriceTable where PriceTable.PlanId = Plan.PlanId)

И вам, вероятно, следует сделать это как часть триггера INSERT в вашей базе данных.

1 голос
/ 18 ноября 2011

Сделайте что-то вроде этого:

if not exists
(
    select *
    from PriceTable
    where PriceName = @priceName
)
begin
    insert into PriceTable(PriceName)
    values(@priceName)
end

Что он делает, это проверяет, проверяет, находится ли PriceName в PriceTable.Если это , а не , то он вставит новый @priceName в PriceTable.По вашему исходному сообщению я не был уверен, какое значение будет иметь значение PlanID, но вы должны понять из моего запроса выше.

0 голосов
/ 18 ноября 2011

Используя MERGE и предполагая, что ваши столбцы ID имеют свойство IDENTITY:

MERGE INTO PriceTable
   USING 
      (
        SELECT p1.ID AS PlanId, sp1.PriceName 
         FROM Plan p1 
            CROSS JOIN StandardPrices sp1
      ) AS SourceTable
   ON PriceTable.PlanId = SourceTable.PlanId 
      AND PriceTable.PriceName = SourceTable.PriceName 
   WHEN NOT MATCHED 
      THEN
   INSERT ( PlanId, PriceName )
            VALUES ( PlanId, PriceName ) ;

Вот более полный набросок, где я опустил кажущиеся избыточными столбцы ID, повысил столбцы name до реляционных ключей, добавил ограничения, использовал согласованные имена между таблицами, изменил MONET на DECIMAL и т. Д .:

CREATE TABLE Plans
(
  plan_name VARCHAR(200) NOT NULL
                         UNIQUE
                         CHECK ( plan_name <> ' ' )
) ;

CREATE TABLE StandardPrices
(
  price_name VARCHAR(200) NOT NULL
                          UNIQUE
                          CHECK ( price_name <> ' ' ),
  default_price DECIMAL(19, 4) NOT NULL
                               CHECK ( default_price >= 0 )
) ;

CREATE TABLE Prices
(
  plan_name VARCHAR(200) NOT NULL
                         REFERENCES Plans ( plan_name ),
  price_name VARCHAR(200) NOT NULL
                          REFERENCES StandardPrices ( price_name ),
  UNIQUE ( plan_name, price_name )
) ;

DECLARE @plan_name_new VARCHAR(200) ;
DECLARE @price_name_1 VARCHAR(200) ;
DECLARE @default_price_1 DECIMAL(19, 4) ;
DECLARE @price_name_2 VARCHAR(200) ;
DECLARE @default_price_2 DECIMAL(19, 4) ;

SET @plan_name_new = 'One'
SET @price_name_1 = 'Day'
SET @default_price_1 = 55 ;
SET @price_name_2 = 'When'
SET @default_price_2 = 99

INSERT INTO Plans ( plan_name )
   VALUES ( @plan_name_new ) ;

INSERT INTO StandardPrices ( price_name, default_price )
   VALUES ( @price_name_1, @default_price_1 ) ;

INSERT INTO StandardPrices ( price_name, default_price )
   VALUES ( @price_name_2, @default_price_2 ) ;

MERGE INTO Prices
   USING 
      (
        SELECT p1.plan_name, sp1.price_name
         FROM Plans p1 
            CROSS JOIN StandardPrices sp1
      ) AS SourceTable
   ON Prices.plan_name = SourceTable.plan_name
      AND Prices.price_name = SourceTable.price_name
   WHEN NOT MATCHED 
      THEN
   INSERT ( plan_name, price_name )
            VALUES ( plan_name, price_name ) ;
0 голосов
/ 18 ноября 2011

Вам необходимо получить список всех планов, ЛЕВЫЙ ВНЕШНИЙ, присоединенный к соответствующей цене. Если запись цены равна нулю, соответствующая связь отсутствует, поэтому добавьте ее.

Возможно, вам понадобится курсор для просмотра результатов и добавления цен.

Что-то вроде ..

SELECT Plan.Id, Price.Id
FROM Plan LEFT OUTER JOIN Price ON Price.PlanId = Plan.Id
WHERE Price.Id = [Your New Price Id]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...