ID 또는 일련 번호 값 검색
적용 대상: .NET Framework .NET .NET Standard
관계형 데이터베이스에서 기본 키는 항상 고유한 값이 들어 있는 열 또는 열의 조합입니다. 기본 키 값을 알면 해당 값이 있는 행을 찾을 수 있습니다. SQL Server, Oracle 및 Microsoft Access/Jet 등과 같은 관계형 데이터베이스 엔진은 기본 키로 지정할 수 있는 자동 증분 열의 작성을 지원합니다. 이러한 값은 서버에 의해 행으로 생성되어 테이블에 추가됩니다. 이를 위해서는 SQL Server에서는 열의 identity 속성을 설정하고, Oracle에서는 시퀀스를 만들고, Microsoft Access에서는 AutoNumber 열을 만듭니다.
또한 DataColumn을 사용하고 AutoIncrement 속성을 true로 설정하면 자동으로 증분하는 값을 생성할 수도 있습니다. 하지만 여러 클라이언트 애플리케이션이 개별적으로 자동 증분 값을 생성하면 DataTable의 개별 인스턴스에서 중복되는 값이 생길 수 있습니다. 따라서 서버가 자동 증분 값을 생성하도록 하면 삽입된 각 행에 대해 생성되는 값을 각 사용자가 검색할 수 있도록 할 때 발생할 수 있는 충돌을 방지할 수 있습니다.
Update
의 DataAdapter
메서드 호출 도중 데이터베이스는 데이터를 출력 매개 변수로, 또는 INSERT 문과 동일한 배치에서 실행되는 SELECT 문의 결과 집합 중 첫 번째 반환되는 레코드로 ADO.NET 애플리케이션에 다시 보낼 수 있습니다. Microsoft SqlClient 데이터 공급자 의 경우 SQL Server는 이러한 값을 검색하고 업데이트 중인 DataRow의 해당 열을 업데이트할 수 있습니다.
참고 항목
자동 증분 값 대신 사용할 수 있는 방법은 NewGuid 개체의 Guid 메서드를 사용하여 새로운 행이 삽입될 때마다 서버로 복사될 수 있는 GUID(Globally Unique Identifier)를 클라이언트 컴퓨터에 생성하는 것입니다. NewGuid
메서드는 값이 복제되지 않을 확률이 높은 알고리즘을 사용하여 16바이트 이진 값을 생성합니다. SQL Server 데이터베이스에서 GUID는 SQL Server가 Transact-SQL uniqueidentifier
함수를 사용하여 자동으로 생성할 수 있는 NEWID()
열에 저장됩니다. GUID를 기본 키로 사용하면 성능에 부정적 영향을 미칠 수 있습니다. SQL Server에서는 전역적으로 고유하지 않을 수도 있지만 더 효율적으로 인덱싱할 수 있는 순차 GUID를 생성하는 NEWSEQUENTIALID()
함수를 지원합니다.
SQL Server ID 열 값 검색
Microsoft SQL Server로 작업하는 경우에는 출력 매개 변수를 사용하는 저장 프로시저를 만들어서 삽입된 행에 대한 ID 값을 반환할 수 있습니다. 다음 테이블에서는 ID 열 값을 검색하는 데 사용할 수 있는 SQL Server의 세 가지 Transact-SQL 함수를 설명합니다.
함수 | 설명 |
---|---|
SCOPE_IDENTITY | 현재 실행 범위 내의 마지막 ID 값을 반환합니다. SCOPE_IDENTITY는 대부분의 시나리오에 권장됩니다. |
@@IDENTITY | 현재 세션의 모든 테이블에서 생성된 마지막 ID 값을 포함합니다. @@IDENTITY는 트리거의 영향을 받을 수 있으며 예상한 ID 값을 반환하지 않을 수도 있습니다. |
IDENT_CURRENT | 모든 세션 및 모든 범위의 특정 테이블에 대해 생성된 마지막 ID 값을 반환합니다. |
다음 저장 프로시저는 Categories 테이블에 행을 삽입하고 출력 매개 변수를 사용하여 Transact-SQL SCOPE_IDENTITY() 함수에서 생성된 새 ID 값을 반환하는 방법을 보여 줍니다.
CREATE PROCEDURE dbo.InsertCategory
@CategoryName nvarchar(15),
@Identity int OUT
AS
INSERT INTO Categories (CategoryName) VALUES(@CategoryName)
SET @Identity = SCOPE_IDENTITY()
그런 다음 저장 프로시저를 InsertCommand 개체의 SqlDataAdapter의 소스로 지정할 수 있습니다. CommandType의 InsertCommand 속성은 StoredProcedure로 설정해야 합니다. ID 출력은 SqlParameter이 ParameterDirection인 Output를 만들어서 검색합니다. InsertCommand
가 처리될 때 자동 증분된 ID 값이 반환되고, 삽입 명령의 UpdatedRowSource 속성을 UpdateRowSource.OutputParameters
또는 UpdateRowSource.Both
로 설정한 경우 이 값이 현재 행의 CategoryID 열에 추가됩니다.
삽입 명령이 새 ID 값을 반환하는 INSERT 문과 SELECT 문이 모두 포함된 배치를 실행하는 경우에는 삽입 명령의 UpdatedRowSource
속성을 UpdateRowSource.FirstReturnedRecord
로 설정하여 새 값을 검색할 수 있습니다.
private static void RetrieveIdentity(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create a SqlDataAdapter based on a SELECT query.
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT CategoryID, CategoryName FROM dbo.Categories",
connection);
//Create the SqlCommand to execute the stored procedure.
adapter.InsertCommand = new SqlCommand("dbo.InsertCategory",
connection);
adapter.InsertCommand.CommandType = CommandType.StoredProcedure;
// Add the parameter for the CategoryName. Specifying the
// ParameterDirection for an input parameter is not required.
adapter.InsertCommand.Parameters.Add(
new SqlParameter("@CategoryName", SqlDbType.NVarChar, 15,
"CategoryName"));
// Add the SqlParameter to retrieve the new identity value.
// Specify the ParameterDirection as Output.
SqlParameter parameter =
adapter.InsertCommand.Parameters.Add(
"@Identity", SqlDbType.Int, 0, "CategoryID");
parameter.Direction = ParameterDirection.Output;
// Create a DataTable and fill it.
DataTable categories = new DataTable();
adapter.Fill(categories);
// Add a new row.
DataRow newRow = categories.NewRow();
newRow["CategoryName"] = "New Category";
categories.Rows.Add(newRow);
adapter.Update(categories);
Console.WriteLine("List All Rows:");
foreach (DataRow row in categories.Rows)
{
{
Console.WriteLine("{0}: {1}", row[0], row[1]);
}
}
}
}
새 ID 값 병합
일반적인 시나리오는 GetChanges
의 DataTable
메서드를 호출하여 변경된 행만 포함된 사본을 만들고 Update
의 DataAdapter
메서드를 호출할 때 새 사본을 사용하는 것입니다. 이 방법은 변경된 행을 업데이트를 수행하는 별도의 구성 요소로 마샬링해야 할 때 특히 유용합니다. 업데이트 후 사본에는 원래 DataTable
로 다시 병합되어야 하는 새 ID 값이 포함될 수 있습니다. 새 ID 값은 DataTable
의 원래 값과 다를 가능성이 큽니다. 병합을 수행하려면 사본에 AutoIncrement 열의 원래 값이 유지되어야 합니다. 그래야 새 ID 값이 포함된 새 행을 추가하지 않고 원래 DataTable
의 기존 행을 찾아 업데이트할 수 있습니다. 하지만 Update
는 업데이트된 각 DataAdapter
에 대해 암시적으로 호출되기 때문에 기본적으로 원래 값은 AcceptChanges
의 DataRow
메서드에 대한 호출 후에 손실됩니다.
DataColumn
업데이트 동안 DataRow
에서 DataAdapter
의 원래 값을 유지하는 방법에는 두 가지가 있습니다.
원래 값을 유지하는 첫 번째 방법은
AcceptChangesDuringUpdate
의DataAdapter
속성을false
로 설정하는 것입니다. 이 구성은 업데이트되는DataTable
의 모든DataRow
에 영향을 줍니다. 자세한 내용과 코드 예제는 AcceptChangesDuringUpdate를 참조하세요.두 번째 방법은
RowUpdated
의DataAdapter
이벤트 처리기에서 코드를 작성하여 Status를 SkipCurrentRow로 설정하는 것입니다.DataRow
가 업데이트되지만 각DataColumn
의 원래 값은 유지됩니다. 이 방법을 사용하면 원하는 행의 원래 값만 유지할 수 있습니다. 예를 들어 StatementType을 검사한 다음 Status이 SkipCurrentRow인 행의StatementType
만Insert
로 설정하여 추가된 행의 원래 값은 유지하고 편집 또는 삭제된 행은 원래 값을 유지하지 않도록 코드를 작성할 수 있습니다.
이 방법 중 하나를 사용하여 DataRow
업데이트 중에 DataAdapter
의 원래 값을 유지하는 경우 Microsoft SqlClient Data Adapter 의 경우 SQL Server에서는 각 DataRow
의 원래 값을 유지하면서 DataColumn
의 현재 값을 출력 매개 변수 또는 결과 집합의 첫 번째 반환 행에서 반환하는 새 값으로 설정하기 위한 일련의 작업을 수행합니다. 먼저 현재 값을 원래 값으로 유지하기 위해 AcceptChanges
의 DataRow
메서드를 호출한 다음 새 값을 할당합니다. 그런 다음 DataRows
속성이 RowState로 설정된 Added의 RowState
속성을 Modified로 설정합니다. 이는 예상하지 않은 동작일 수 있습니다.
업데이트되는 각 DataRow에 명령 결과가 적용되는 방법은 각 UpdatedRowSource의 DbCommand 속성에 따라 결정됩니다. 이 속성은 UpdateRowSource
열거형의 값으로 설정됩니다.
다음 테이블에서는 UpdateRowSource
열거형 값이 업데이트된 행의 RowState 속성에 영향을 주는 방식을 설명합니다.
멤버 이름 | 설명 |
---|---|
Both | AcceptChanges 가 호출되고 출력 매개 변수 값 또는 반환된 결과 집합 중 첫 번째 행의 값이 업데이트되는 DataRow 에 추가됩니다. 적용할 값이 없으면 RowState 는 Unchanged가 됩니다. |
FirstReturnedRecord | 행이 반환되면 AcceptChanges 가 호출되고 행이 DataTable 의 변경된 행으로 매핑되어 RowState 가 Modified 로 설정됩니다. 행이 반환되지 않으면 AcceptChanges 가 호출되지 않고 RowState 는 Added 로 유지됩니다. |
None | 반환된 매개 변수 또는 행은 무시됩니다. AcceptChanges 가 호출되지 않고 RowState 는 Added 로 유지됩니다. |
OutputParameters | AcceptChanges 가 호출되고 모든 출력 매개 변수가 DataTable 에서 변경된 행으로 매핑되어 RowState 가 Modified 로 설정됩니다. 출력 매개 변수가 없으면 RowState 는 Unchanged 가 됩니다. |
예시
이 예제에서는 DataTable
에서 변경된 행을 추출하고 SqlDataAdapter를 사용하여 데이터 원본을 업데이트하고 새 ID 열 값을 검색하는 방법을 보여 줍니다. InsertCommand는 두 개의 Transact-SQL 문을 실행합니다. 첫 번째는 INSERT 문이고, 두 번째는 SCOPE_IDENTITY 함수를 사용하여 ID 값을 검색하는 SELECT 문입니다.
INSERT INTO dbo.Shippers (CompanyName)
VALUES (@CompanyName);
SELECT ShipperID, CompanyName FROM dbo.Shippers
WHERE ShipperID = SCOPE_IDENTITY();
삽입 명령의 UpdatedRowSource
속성은 UpdateRowSource.FirstReturnedRow
로 설정되고 MissingSchemaAction의 DataAdapter
속성은 MissingSchemaAction.AddWithKey
로 설정됩니다. DataTable
이 채워지고 코드는 DataTable
에 새 행을 추가합니다. 그런 다음 변경된 행이 새 DataTable
로 추출되고, DataTable이 DataAdapter
로 전달되고 나면 DataAdapter에서 서버를 업데이트합니다.
private static void MergeIdentityColumns(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create the DataAdapter
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT ShipperID, CompanyName FROM dbo.Shippers",
connection);
//Add the InsertCommand to retrieve new identity value.
adapter.InsertCommand = new SqlCommand(
"INSERT INTO dbo.Shippers (CompanyName) " +
"VALUES (@CompanyName); " +
"SELECT ShipperID, CompanyName FROM dbo.Shippers " +
"WHERE ShipperID = SCOPE_IDENTITY();", connection);
// Add the parameter for the inserted value.
adapter.InsertCommand.Parameters.Add(
new SqlParameter("@CompanyName", SqlDbType.NVarChar, 40,
"CompanyName"));
adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.Both;
// MissingSchemaAction adds any missing schema to
// the DataTable, including identity columns
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
// Fill the DataTable.
DataTable shipper = new DataTable();
adapter.Fill(shipper);
// Add a new shipper.
DataRow newRow = shipper.NewRow();
newRow["CompanyName"] = "New Shipper";
shipper.Rows.Add(newRow);
// Add changed rows to a new DataTable. This
// DataTable will be used by the DataAdapter.
DataTable dataChanges = shipper.GetChanges();
// Add the event handler.
adapter.RowUpdated +=
new SqlRowUpdatedEventHandler(OnRowUpdated);
adapter.Update(dataChanges);
connection.Close();
// Merge the updates.
shipper.Merge(dataChanges);
// Commit the changes.
shipper.AcceptChanges();
Console.WriteLine("Rows after merge.");
foreach (DataRow row in shipper.Rows)
{
{
Console.WriteLine("{0}: {1}", row[0], row[1]);
}
}
}
}
OnRowUpdated
이벤트 처리기는 StatementType의 SqlRowUpdatedEventArgs을 검사하여 행이 삽입된 행인지 확인합니다. 행이 삽입된 행인 경우에는 Status 속성이 SkipCurrentRow로 설정됩니다. 행이 업데이트되지만 행의 원래 데이터는 유지됩니다. 프로시저의 본문에서 Merge 메서드가 호출되어 새 ID 값을 원래 DataTable
로 병합하고, 마지막으로 AcceptChanges
가 호출됩니다.
protected static void OnRowUpdated(
object sender, SqlRowUpdatedEventArgs e)
{
// If this is an insert, then skip this row.
if (e.StatementType == StatementType.Insert)
{
e.Status = UpdateStatus.SkipCurrentRow;
}
}
ID 값 검색
열의 값이 고유해야 하는 경우에는 열을 ID로 설정하는 경우가 많습니다. 새 데이터의 ID 값이 필요한 경우도 있습니다. 이 샘플에서는 ID 값을 검색하는 방법을 보여 줍니다.
데이터를 삽입하고 ID 값을 반환하는 저장 프로시저를 만듭니다.
새 데이터를 삽입하고 결과를 표시하는 명령을 실행합니다.
SqlDataAdapter를 사용하여 새 데이터를 삽입하고 결과를 표시합니다.
샘플을 컴파일하고 실행하기 전에 다음 스크립트를 사용하여 샘플 데이터베이스를 만들어야 합니다.
USE [master]
GO
CREATE DATABASE [MySchool]
GO
USE [MySchool]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE procedure [dbo].[CourseExtInfo] @CourseId int
as
select c.CourseID,c.Title,c.Credits,d.Name as DepartmentName
from Course as c left outer join Department as d on c.DepartmentID=d.DepartmentID
where c.CourseID=@CourseId
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create procedure [dbo].[DepartmentInfo] @DepartmentId int,@CourseCount int output
as
select @CourseCount=Count(c.CourseID)
from course as c
where c.DepartmentID=@DepartmentId
select d.DepartmentID,d.Name,d.Budget,d.StartDate,d.Administrator
from Department as d
where d.DepartmentID=@DepartmentId
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create PROCEDURE [dbo].[GetDepartmentsOfSpecifiedYear]
@Year int,@BudgetSum money output
AS
BEGIN
SELECT @BudgetSum=SUM([Budget])
FROM [MySchool].[dbo].[Department]
Where YEAR([StartDate])=@Year
SELECT [DepartmentID]
,[Name]
,[Budget]
,[StartDate]
,[Administrator]
FROM [MySchool].[dbo].[Department]
Where YEAR([StartDate])=@Year
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[GradeOfStudent]
-- Add the parameters for the stored procedure here
@CourseTitle nvarchar(100),@FirstName nvarchar(50),
@LastName nvarchar(50),@Grade decimal(3,2) output
AS
BEGIN
select @Grade=Max(Grade)
from [dbo].[StudentGrade] as s join [dbo].[Course] as c on
s.CourseID=c.CourseID join [dbo].[Person] as p on s.StudentID=p.PersonID
where c.Title=@CourseTitle and p.FirstName=@FirstName
and p.LastName= @LastName
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[InsertPerson]
-- Add the parameters for the stored procedure here
@FirstName nvarchar(50),@LastName nvarchar(50),
@PersonID int output
AS
BEGIN
insert [dbo].[Person](LastName,FirstName) Values(@LastName,@FirstName)
set @PersonID=SCOPE_IDENTITY()
END
Go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Course]([CourseID] [nvarchar](10) NOT NULL,
[Year] [smallint] NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[Credits] [int] NOT NULL,
[DepartmentID] [int] NOT NULL,
CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED
(
[CourseID] ASC,
[Year] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Department]([DepartmentID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Budget] [money] NOT NULL,
[StartDate] [datetime] NOT NULL,
[Administrator] [int] NULL,
CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED
(
[DepartmentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Person]([PersonID] [int] IDENTITY(1,1) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[HireDate] [datetime] NULL,
[EnrollmentDate] [datetime] NULL,
[Picture] [varbinary](max) NULL,
CONSTRAINT [PK_School.Student] PRIMARY KEY CLUSTERED
(
[PersonID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[StudentGrade]([EnrollmentID] [int] IDENTITY(1,1) NOT NULL,
[CourseID] [nvarchar](10) NOT NULL,
[StudentID] [int] NOT NULL,
[Grade] [decimal](3, 2) NOT NULL,
CONSTRAINT [PK_StudentGrade] PRIMARY KEY CLUSTERED
(
[EnrollmentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create view [dbo].[EnglishCourse]
as
select c.CourseID,c.Title,c.Credits,c.DepartmentID
from Course as c join Department as d on c.DepartmentID=d.DepartmentID
where d.Name=N'English'
GO
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1045', 2012, N'Calculus', 4, 7)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1061', 2012, N'Physics', 4, 1)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2021', 2012, N'Composition', 3, 2)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2042', 2012, N'Literature', 4, 2)
SET IDENTITY_INSERT [dbo].[Department] ON
INSERT [dbo].[Department] ([DepartmentID], [Name], [Budget], [StartDate], [Administrator]) VALUES (1, N'Engineering', 350000.0000, CAST(0x0000999C00000000 AS DateTime), 2)
INSERT [dbo].[Department] ([DepartmentID], [Name], [Budget], [StartDate], [Administrator]) VALUES (2, N'English', 120000.0000, CAST(0x0000999C00000000 AS DateTime), 6)
INSERT [dbo].[Department] ([DepartmentID], [Name], [Budget], [StartDate], [Administrator]) VALUES (4, N'Economics', 200000.0000, CAST(0x0000999C00000000 AS DateTime), 4)
INSERT [dbo].[Department] ([DepartmentID], [Name], [Budget], [StartDate], [Administrator]) VALUES (7, N'Mathematics', 250024.0000, CAST(0x0000999C00000000 AS DateTime), 3)
SET IDENTITY_INSERT [dbo].[Department] OFF
SET IDENTITY_INSERT [dbo].[Person] ON
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (1, N'Hu', N'Nan', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (2, N'Norman', N'Laura', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (3, N'Olivotto', N'Nino', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (4, N'Anand', N'Arturo', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (5, N'Jai', N'Damien', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (6, N'Holt', N'Roger', CAST(0x000097F100000000 AS DateTime), NULL)
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (7, N'Martin', N'Randall', CAST(0x00008B1A00000000 AS DateTime), NULL)
SET IDENTITY_INSERT [dbo].[Person] OFF
SET IDENTITY_INSERT [dbo].[StudentGrade] ON
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (1, N'C1045', 1, CAST(3.50 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (2, N'C1045', 2, CAST(3.00 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (3, N'C1045', 3, CAST(2.50 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (4, N'C1045', 4, CAST(4.00 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (5, N'C1045', 5, CAST(3.50 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (6, N'C1061', 1, CAST(4.00 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (7, N'C1061', 3, CAST(3.50 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (8, N'C1061', 4, CAST(2.50 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (9, N'C1061', 5, CAST(1.50 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (10, N'C2021', 1, CAST(2.50 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (11, N'C2021', 2, CAST(3.50 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (12, N'C2021', 4, CAST(3.00 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (13, N'C2021', 5, CAST(3.00 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (14, N'C2042', 1, CAST(2.00 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (15, N'C2042', 2, CAST(3.50 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (16, N'C2042', 3, CAST(4.00 AS Decimal(3, 2)))
INSERT [dbo].[StudentGrade] ([EnrollmentID], [CourseID], [StudentID], [Grade]) VALUES (17, N'C2042', 5, CAST(3.00 AS Decimal(3, 2)))
SET IDENTITY_INSERT [dbo].[StudentGrade] OFF
ALTER TABLE [dbo].[Course] WITH CHECK ADD CONSTRAINT [FK_Course_Department] FOREIGN KEY([DepartmentID])
REFERENCES [dbo].[Department] ([DepartmentID])
GO
ALTER TABLE [dbo].[Course] CHECK CONSTRAINT [FK_Course_Department]
GO
ALTER TABLE [dbo].[StudentGrade] WITH CHECK ADD CONSTRAINT [FK_StudentGrade_Student] FOREIGN KEY([StudentID])
REFERENCES [dbo].[Person] ([PersonID])
GO
ALTER TABLE [dbo].[StudentGrade] CHECK CONSTRAINT [FK_StudentGrade_Student]
GO
코드 목록은 다음과 같습니다.
static void Main(string[] args)
{
String SqlDbConnectionString = "Data Source=(local);Initial Catalog=MySchool;Integrated Security=True;";
InsertPersonInCommand(SqlDbConnectionString, "Janice", "Galvin");
Console.WriteLine();
InsertPersonInAdapter(SqlDbConnectionString, "Peter", "Krebs");
Console.WriteLine();
Console.WriteLine("Please press any key to exit.....");
Console.ReadKey();
}
// Using stored procedure to insert a new row and retrieve the identity value
static void InsertPersonInCommand(String connectionString, String firstName, String lastName)
{
String commandText = "dbo.InsertPerson";
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand(commandText, conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@FirstName", firstName));
cmd.Parameters.Add(new SqlParameter("@LastName", lastName));
SqlParameter personId = new SqlParameter("@PersonID", SqlDbType.Int);
personId.Direction = ParameterDirection.Output;
cmd.Parameters.Add(personId);
conn.Open();
cmd.ExecuteNonQuery();
Console.WriteLine("Person Id of new person:{0}", personId.Value);
}
}
}
// Using stored procedure in adapter to insert new rows and update the identity value.
static void InsertPersonInAdapter(String connectionString, String firstName, String lastName)
{
String commandText = "dbo.InsertPerson";
using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlDataAdapter mySchool = new SqlDataAdapter("Select PersonID,FirstName,LastName from [dbo].[Person]", conn);
mySchool.InsertCommand = new SqlCommand(commandText, conn);
mySchool.InsertCommand.CommandType = CommandType.StoredProcedure;
mySchool.InsertCommand.Parameters.Add(
new SqlParameter("@FirstName", SqlDbType.NVarChar, 50, "FirstName"));
mySchool.InsertCommand.Parameters.Add(
new SqlParameter("@LastName", SqlDbType.NVarChar, 50, "LastName"));
SqlParameter personId = mySchool.InsertCommand.Parameters.Add(new SqlParameter("@PersonID", SqlDbType.Int, 0, "PersonID"));
personId.Direction = ParameterDirection.Output;
DataTable persons = new DataTable();
mySchool.Fill(persons);
DataRow newPerson = persons.NewRow();
newPerson["FirstName"] = firstName;
newPerson["LastName"] = lastName;
persons.Rows.Add(newPerson);
mySchool.Update(persons);
Console.WriteLine("Show all persons:");
ShowDataTable(persons, 14);
}
}
private static void ShowDataTable(DataTable table, Int32 length)
{
foreach (DataColumn col in table.Columns)
{
Console.Write("{0,-" + length + "}", col.ColumnName);
}
Console.WriteLine();
foreach (DataRow row in table.Rows)
{
foreach (DataColumn col in table.Columns)
{
if (col.DataType.Equals(typeof(DateTime)))
Console.Write("{0,-" + length + ":d}", row[col]);
else if (col.DataType.Equals(typeof(Decimal)))
Console.Write("{0,-" + length + ":C}", row[col]);
else
Console.Write("{0,-" + length + "}", row[col]);
}
Console.WriteLine();
}
}