Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以在SQL存储过程中分配变量吗?_Sql_Mysql_Sql Server_Stored Procedures - Fatal编程技术网

我可以在SQL存储过程中分配变量吗?

我可以在SQL存储过程中分配变量吗?,sql,mysql,sql-server,stored-procedures,Sql,Mysql,Sql Server,Stored Procedures,我正在执行SQL插入以填充我的表。我在一个表中有一个唯一生成的ID,我想在另一个表中使用该ID进行连接。这可能吗 .NETMVC- using (SqlConnection connect = new SqlConnection(connections)) { SqlCommand command = new SqlCommand("ContactInfo_Add", connect); command.Parameters.Add(new SqlParameter("name"

我正在执行SQL插入以填充我的表。我在一个表中有一个唯一生成的ID,我想在另一个表中使用该ID进行连接。这可能吗

.NETMVC-

using (SqlConnection connect = new SqlConnection(connections))
{
    SqlCommand command = new SqlCommand("ContactInfo_Add", connect);
    command.Parameters.Add(new SqlParameter("name", name));
    command.Parameters.Add(new SqlParameter("address", address));
    command.Parameters.Add(new SqlParameter("Product", name));
    command.Parameters.Add(new SqlParameter("Quantity", address));
    command.Parameters.Add(new SqlParameter("DueDate", city));
    connect.Open();
    command.ExecuteNonQuery();
}
SQL SERVER-

ALTER PROCEDURE [dbo].[Contact_Add]
@name varchar(40),
@address varchar(60),
@Product varchar(40),
@Quantity varchar(5),
@DueDate datetime
AS 
BEGIN
     SET NOCOUNT ON;

     INSERT INTO DBO.PERSON
     (Name, Address) VALUES (@name, @address)
     INSERT INTO DBO.PRODUCT_DATA
     (PersonID, Product, Quantity, DueDate) VALUES (@Product, @Quantity, @DueDate)
END
代码插入得很好。如何提取自动生成的PersonID以在产品数据中使用?

您可以使用以获取最后插入的标识值:

DECLARE @PersonID INT

INSERT INTO dbo.Person (Name, Address)
VALUES (@Name, @Address)

SET @PersonID = SCOPE_IDENTITY()

INSERT INTO dbo.Product_Data (PersonID, Product, Quantity, DueDate)
VALUES (@PersonID, @Product, @Quantity, @DueDate)
您可以使用获取最后插入的标识值:

DECLARE @PersonID INT

INSERT INTO dbo.Person (Name, Address)
VALUES (@Name, @Address)

SET @PersonID = SCOPE_IDENTITY()

INSERT INTO dbo.Product_Data (PersonID, Product, Quantity, DueDate)
VALUES (@PersonID, @Product, @Quantity, @DueDate)
您不需要使用SCOPE_标识,只需使用输出和单个INSERT语句! 这确实需要SQL Server 2005及更高版本

试试这个:

摆桌子

CREATE TABLE Test1 (PersonID int identity(1,1), Name varchar(40), Address varchar(60))
CREATE TABLE Test2 (PersonID int, product varchar(40),Quantity varchar(5),DueDate datetime)
创建过程

CREATE PROCEDURE TestSP
@name varchar(40),
@address varchar(60),
@Product varchar(40),
@Quantity varchar(5),
@DueDate datetime
AS 
BEGIN
     SET NOCOUNT ON;

     INSERT INTO Test1
             (Name, Address)
             OUTPUT INSERTED.PersonID, @Product, @Quantity, @DueDate
             INTO Test2
         VALUES 
             (@name, @address)

END
测试代码

exec TestSP 'name','address','product',123,'1/1/2010'
select * from Test1
select * from Test2
输出

PersonID    Name                 Address
----------- -------------------- -----------------------
1           name                 address

(1 row(s) affected)

PersonID    product   Quantity DueDate
----------- --------- -------- -----------------------
1           product   123      2010-01-01 00:00:00.000

(1 row(s) affected)
您不需要使用SCOPE_标识,只需使用输出和单个INSERT语句! 这确实需要SQL Server 2005及更高版本

试试这个:

摆桌子

CREATE TABLE Test1 (PersonID int identity(1,1), Name varchar(40), Address varchar(60))
CREATE TABLE Test2 (PersonID int, product varchar(40),Quantity varchar(5),DueDate datetime)
创建过程

CREATE PROCEDURE TestSP
@name varchar(40),
@address varchar(60),
@Product varchar(40),
@Quantity varchar(5),
@DueDate datetime
AS 
BEGIN
     SET NOCOUNT ON;

     INSERT INTO Test1
             (Name, Address)
             OUTPUT INSERTED.PersonID, @Product, @Quantity, @DueDate
             INTO Test2
         VALUES 
             (@name, @address)

END
测试代码

exec TestSP 'name','address','product',123,'1/1/2010'
select * from Test1
select * from Test2
输出

PersonID    Name                 Address
----------- -------------------- -----------------------
1           name                 address

(1 row(s) affected)

PersonID    product   Quantity DueDate
----------- --------- -------- -----------------------
1           product   123      2010-01-01 00:00:00.000

(1 row(s) affected)

您可以在不使用SCOPE_IDENTITY的情况下将insert插入到两个表中,在单个insert语句中,查看我的答案,了解如何执行:@KM:我知道您可以使用一个使用OUTPUT INSERTED子句的单个语句。一般来说,我发现单独的语句更易于阅读/维护:每项工作一条语句。您可以在两个表中插入insert,而无需使用SCOPE_标识。在一条insert语句中,请查看我的答案,了解如何使用:@KM:我知道您可以使用一条使用OUTPUT INSERTED子句的语句。一般来说,我发现单独的语句更易于阅读/维护:每项工作一条语句。同意使用范围标识工作,直到有人更改存储过程,导致返回的最后一个值不正确。oopst这是一种向日志表添加项目的简单方法。您甚至可以一次有多个输出语句。此外,如果将删除,它将返回一个结果集。例如,将输出INSERTED.*置于Test2和值之间。运行过程TestSP时,它将插入两个表,并返回一个结果集,其中包含Test1表的两个insert和一个SELECT in one insert!。约定使用范围标识工作,直到有人更改存储过程,导致返回的最后一个值不正确为止。oopst这是一种向日志表添加项目的简单方法。您甚至可以一次有多个输出语句。此外,如果将删除,它将返回一个结果集。例如,将输出INSERTED.*置于Test2和值之间。运行过程TestSP时,它将插入两个表,并返回一个结果集,其中包含Test1表的两个insert和一个SELECT in one insert!。用户54197查看KM的答案和我对它的评论。如果有人在不知情的情况下更改了您的存储过程,使用作用域标识返回PersonID可能会出现一些问题。@msarchet:是否要详细说明这些潜在问题?当然,如果有人在不知道存储过程如何工作的情况下更改存储过程,他们可能会破坏存储过程,但这与SCOPE_标识本身无关-他们很可能会破坏输出插入子句。正如您刚才所说,这不是SCOPE_标识本身的问题,这非常有效。使用插入的输出更有把握,因为如果有人更改存储过程的顺序,它不会中断。这并不完美,因为很明显,无论您如何返回值,总有人会破坏您的SP。使用@variable int output这样的参数是获取输出的最明显的方法。但仍然有人可以打破这一点,但这更难。在我使用SQL Server十年的时间里!,我从未见过有人更改存储进程以获得错误的scope\u标识。我想这可能会发生,但一般来说,我不会让任何人编写不知道自己在做什么的程序。但是,如果您使用的是较新版本的SQl Server,则输出子句是更好的选择,原因有很多,包括您可以返回一个不是通过标识生成的值,甚至不是通过多个值生成的值。user54197请查看KM的答案和我对它的评论。如果有人在不知情的情况下更改了您的存储过程,使用作用域标识返回PersonID可能会出现一些问题。@msarchet:是否要详细说明这些潜在问题?当然,如果有人在不知道存储过程如何工作的情况下更改存储过程,他们可能会破坏存储过程,但这与SCOPE_标识本身无关-他们很可能会破坏输出插入子句。正如您刚才所说,这不是SCOPE_标识本身的问题,这非常有效。使用插入的输出更有把握,因为如果有人更改存储过程的顺序,它不会中断。这并不完美,因为很明显,无论您如何返回值,总有人会破坏您的SP。使用@variable int output这样的参数是获取输出的最明显的方法。但还是有人可以
我要打破这一点,但这更难。在我使用SQL Server的十年时间里!,我从未见过有人更改存储进程以获得错误的scope\u标识。我想这可能会发生,但一般来说,我不会让任何人编写不知道自己在做什么的程序。但是,如果您使用的是较新版本的SQl Server,则输出子句是更好的选择,原因有很多,包括您可以返回一个不是通过标识生成的值,甚至可以返回多个值。