#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».
Мои вопросы / ошибки:
-
Являются ли мои таблицы логическими? Должен ли я использовать имя пользователя покупателя в качестве PK для адреса / идентификатора контакта (мой учитель предложил это, но я думаю, что это плохая практика)
-
При создании моей процедуры я получаю красные строки на [dbo] .[покупатель], [dbo]. [address_id], [dbo] .[contact_id], могу ли я игнорировать это?
-
Как мне исправить ошибки?
Заранее спасибо.
Ответ №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 . , , Редактирование вопроса после того, как на него был дан ответ — особенно таким образом, чтобы сделать ответы недействительными — считается грубым.