SQL создает процедуру, но не видит мои таблицы

#sql #sql-server #ssms

#sql #sql-server #ssms

Вопрос:

Я создал новую базу данных с именем sample1 . В нем я создал 3 таблицы: «адрес, контакт и покупатель»

 CREATE TABLE address
(
    address_id int NOT NULL identity(1,1) primary key,
    street_name varchar(30)
);

CREATE TABLE contact
(
    contact_id int NOT NULL identity(1,1) primary key,
    phone_num varchar(20) NOT NULL,
    address_id int NOT NULL foreign key REFERENCES address(address_id)
);

CREATE TABLE buyer
(
    username char(20) NOT NULL primary key,
    name char(40) NOT NULL, 
    contact_id int NOT NULL foreign key REFERENCES contact(contact_id)
);
  

Таблицы были созданы успешно, теперь я пытаюсь создать хранимую процедуру следующим образом:

 create procedure csc
(
    @username char(20),
    @address_id int,
    @contact_id int
)
as
set nocount on;
insert into [dbo].[buyer] values (@username);
insert into [dbo].[address_id] values (@address_id);
insert into [dbo].[contact_id] values (@contact_id);
go
  

Но я получаю следующие ошибки:

Сообщение 137, уровень 15, состояние 2, строка 4
Должна объявлять скалярную переменную «@username».

Сообщение 137, уровень 15, состояние 2, строка 10
Должна объявлять скалярную переменную «@username».

Сообщение 137, уровень 15, состояние 2, строка 11
Должна объявлять скалярную переменную «@address_id».

Сообщение 137, уровень 15, состояние 2, строка 12
Должна объявлять скалярную переменную «@contact_id».

Мои вопросы / ошибки:

  1. Являются ли мои таблицы логическими? Должен ли я использовать имя пользователя покупателя в качестве PK для адреса / идентификатора контакта (мой учитель предложил это, но я думаю, что это плохая практика)

  2. При создании моей процедуры я получаю красные строки на [dbo] .[покупатель], [dbo]. [address_id], [dbo] .[contact_id], могу ли я игнорировать это?

  3. Как мне исправить ошибки?

Заранее спасибо.

Ответ №1:

1, являются ли мои таблицы логическими? должен ли я использовать имя пользователя покупателя в качестве PK для адреса / идентификатора контакта (мой учитель предложил это, но я думаю, что это плохая практика)

Это зависит от того, всегда ли покупатель определяется своим именем пользователя, и оно не будет обновляться. Это давний спор между естественными и суррогатными ключами, вы можете использовать Google и найти несколько довольно убедительных аргументов для любой стороны. Если вы считаете, что это плохая практика, вам нужно будет объяснить, почему вы так думаете. Я бы, конечно, избегал использования типа данных char, если вы действительно не хотите его использовать, он будет заполнять ваши данные до указанной длины.

2, при создании моей процедуры я получаю красные строки на [dbo] .[покупатель], [dbo]. [address_id], [dbo] .[contact_id], могу ли я игнорировать это?

Это потому, что, когда SSMS просматривал в последний раз, эти таблицы не существовали. Если вы нажмете CTRL SHIFT R, вы обновите intelligence, и он снова проверит. Все равно произойдет сбой, потому что address_id и contact_id являются таблицами.

3, как мне исправить ошибки?

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

например

 insert into [dbo].[buyer] (username, name, contact_id) values (@username, @name, @contact_id);
  

Но .. вы одновременно вставляете строку contact и объявили ее как столбец identity, должны ли вы действительно знать значение этого столбца уже или вы должны вставлять другие значения в таблицу и генерировать с ним новый contact_id?

Возможно, ваша процедура действительно должна начаться

 create procedure csc(
    @username char(20),
    @name char(40),
    @street_name varchar(30),
    @phone_num varchar(20)
)
  

А затем создайте свои инструкции insert из этих данных. Что-то вроде:

 as
set nocount on;
declare @address_id int;
declare @contact_id int;

insert into [dbo].[address] (street_name) values (@street_name);
set @address_id = SCOPE_IDENTITY() ;

insert into [dbo].contact (phone_num, address_id) values (@phone_num, @address_id);
set @contact_id = SCOPE_IDENTITY() ;

insert into [dbo].[buyer] (username, name, contact_id) values (@username, @name, @contact_id);
go
  

И для демонстрации:

 exec csc 'andy','andy','Nice Road',42

select * from buyer;
select * from contact;
select * from address;
username             name                                     contact_id
-------------------- ---------------------------------------- -----------
andy                 andy                                     3

(1 row affected)

contact_id  phone_num            address_id
----------- -------------------- -----------
3           42                   3

(1 row affected)

address_id  street_name
----------- ------------------------------
3           Nice Road

(1 row affected)


  

Ответ №2:

Похоже, у вас есть пара опечаток. Попробуйте сделать это так

 create procedure csc
  @username char(20),
  @address_id int,
  @contact_id int
as
set nocount on;
insert into [dbo].[buyer] values (@username);
insert into [dbo].[address] values (@address_id);
insert into [dbo].[contact] values (@contact_id);
go
  

Ответ №3:

Используйте begin / end block:

 create procedure csc (
    @username char(20),
    @address_id int,
    @contact_id int
) as
begin
    set nocount on;
    insert into [dbo].[buyer] values (@username);
    insert into [dbo].[address_id] values (@address_id);
    insert into [dbo].[contact_id] values (@contact_id);
end;
  

Вперед

Комментарии:

1. это избавило меня от ошибок, НО я получаю это при ее запуске: сообщение 213, уровень 16, состояние 1, процедура csc, строка 9 [Строка запуска пакета 1] Имя столбца или количество предоставленных значений не соответствует определению таблицы. и когда я пытаюсь запустить процедуру, она заявляет, что она не найдена.

2. @gatorade2131 . . . Это меня не удивляет. Это отвечает на вопрос, который вы задали здесь. Я бы посоветовал вам задать новый вопрос. Предоставьте образцы данных, желаемые результаты и четкое объяснение того, чего вы хотите достичь.

3. @GordonLinoff посмотрите выше, чтобы найти действительно полезный ответ, в отличие от того, что вы сказали. в любом случае спасибо.

4. @gatorade2131 . , , Редактирование вопроса после того, как на него был дан ответ — особенно таким образом, чтобы сделать ответы недействительными — считается грубым.