SQL 正在创建过程,但它看不到我的表

SQL Creating a procedure, but it doesn't see my tables

我创建了一个名为 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

但我收到以下错误:

Msg 137, Level 15, State 2, Line 4
Must declare the scalar variable "@username".

Msg 137, Level 15, State 2, Line 10
Must declare the scalar variable "@username".

Msg 137, Level 15, State 2, Line 11
Must declare the scalar variable "@address_id".

Msg 137, Level 15, State 2, Line 12
Must declare the scalar variable "@contact_id".

我的问题/错误:

  1. 我的表格合乎逻辑吗?我是否应该使用买家用户名作为地址/联系人 ID 的 PK(我的老师建议这样做,但我认为这是不好的做法)

  2. 创建程序时,我在 [dbo].[buyer]、[dbo] 上收到红线。 [address_id], [dbo].[contact_id], 我可以忽略这些吗?

  3. 我该如何修复这些错误?

提前致谢。

使用 begin/end 块:

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;

您好像有几个错别字。试试这个

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

1, are my tables logical? should I be using buyer username as the PK for address / contact ID (my teacher suggested this, but I think it's bad practice)

这取决于买家是否始终由他们的用户名定义并且不会更新。这是自然键和代理键之间由来已久的辩论,您可以使用 google 并为任何一方找到一些非常有说服力的论据。如果您认为这是不好的做法,那么您需要能够解释您为什么这么认为。我肯定会避免使用 char 数据类型,除非你真的想使用它,它会将你的数据填充到指定的长度。

2, when creating my procedure, I get red lines on [dbo].[buyer], [dbo]. [address_id], [dbo].[contact_id], can I ignore these?

那是因为上次查看 SSMS 时,那些 table 不存在。如果你按CTRL+SHIFT+R,你会刷新情报,它会再次检查。它仍然会失败,因为 address_id 和 contact_id 都不是 table。

3, how in the world do I fix the errors?

您修复 table 个名称。但是一旦你这样做了,你就会遇到另一个错误,因为你没有指定你的值应该插入到哪一列,而且它可以使用多个列。问题是您的代码想要插入您的主键列但没有其他数据 - 所以您确实需要完成您的代码以便输入所有必需的数据并明确提及它们要插入的列。

例如

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

但是..您同时插入联系人行并且已将其声明为标识列,您是否真的已经知道该列的值,或者您是否应该将其他值插入 table 并用它生成一个新的 contact_id?

也许你的程序真的应该开始了

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

然后根据该数据构建您的插入语句。类似于:

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)