Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Dotyczy: .NET Framework
.NET
Standard
Klucz podstawowy w relacyjnej bazie danych to kolumna lub kombinacja kolumn, które zawsze zawierają unikatowe wartości. Znajomość wartości klucza podstawowego pozwala zlokalizować wiersz, który go zawiera. Silniki relacyjnych baz danych, takie jak SQL Server, Oracle i Microsoft Access/Jet, obsługują tworzenie automatycznie inkrementowanych kolumn, które można wyznaczyć jako klucze podstawowe. Te wartości są generowane przez serwer w miarę dodawania wierszy do tabeli. W programie SQL Server ustawiasz właściwość identyczności kolumny, w programie Oracle tworzysz sekwencję, a w programie Microsoft Access tworzysz kolumnę AutoNumerowanie.
Elementu DataColumn można również użyć do automatycznego generowania wartości przyrostowych, ustawiając właściwość AutoIncrement na prawda. Możesz jednak uzyskać powielone wartości w oddzielnych wystąpieniach DataTable, jeśli wiele aplikacji klienckich niezależnie generuje wartości automatycznie rosnące. Generowanie przez serwer automatycznie przyrastających wartości eliminuje potencjalne konflikty, umożliwiając każdemu użytkownikowi pobranie wygenerowanej wartości dla każdego wstawionego wiersza.
Podczas wywołania metody Update obiektu DataAdapter baza danych może przekazywać dane do aplikacji ADO.NET jako parametry wyjściowe lub jako pierwszy zwrócony rekord zestawu wyników z instrukcji SELECT, wykonanej w tej samej partii co instrukcja INSERT. Dostawca danych Microsoft SqlClient dla programu SQL Server może pobierać te wartości i zaktualizować odpowiednie kolumny w DataRow w trakcie aktualizacji.
Uwaga / Notatka
Alternatywą dla użycia wartości automatycznego zwiększania jest użycie metody obiektu do wygenerowania identyfikatora GUID, czyli globalnego unikatowego identyfikatora, na komputerze klienckim, a następnie skopiowanie go na serwer podczas wstawiania każdego nowego wiersza. Metoda NewGuid generuje 16-bajtową wartość binarną utworzoną przy użyciu algorytmu, który zapewnia wysokie prawdopodobieństwo, że żadna wartość nie zostanie zduplikowana. W bazie danych programu SQL Server identyfikator GUID jest przechowywany w uniqueidentifier kolumnie, którą program SQL Server może automatycznie wygenerować przy użyciu funkcji Transact-SQL NEWID() . Użycie identyfikatora GUID jako klucza podstawowego może niekorzystnie wpłynąć na wydajność. Program SQL Server zapewnia obsługę NEWSEQUENTIALID() funkcji, która generuje sekwencyjny identyfikator GUID, który nie jest gwarantowany globalnie unikatowy, ale może być indeksowany wydajniej.
Pobieranie wartości kolumn tożsamości programu SQL Server
Podczas pracy z programem Microsoft SQL Server można utworzyć procedurę składowaną z parametrem wyjściowym, aby zwrócić wartość tożsamości dla wstawionego wiersza. W poniższej tabeli opisano trzy funkcje języka Transact-SQL w programie SQL Server, które mogą służyć do pobierania wartości kolumn tożsamości.
| Funkcja | Description |
|---|---|
| SCOPE_IDENTITY | Zwraca ostatnią wartość identyfikatora w aktualnym kontekście wykonania. SCOPE_IDENTITY jest zalecana w większości scenariuszy. |
| @@IDENTITY | Zawiera ostatnią wartość tożsamości wygenerowaną w dowolnej tabeli w bieżącej sesji. Na @@IDENTITY mogą mieć wpływ wyzwalacze, co może skutkować nieoczekiwanym zwrotem wartości tożsamości. |
| IDENT_CURRENT | Zwraca ostatnią wartość tożsamości wygenerowaną dla określonej tabeli w dowolnej sesji i dowolnym zakresie. |
Poniższa procedura składowana pokazuje, jak wstawić wiersz do tabeli Categories i użyć parametru wyjściowego, aby zwrócić nową wartość tożsamości wygenerowaną przez funkcję Transact-SQL SCOPE_IDENTITY().
CREATE PROCEDURE dbo.InsertCategory
@CategoryName nvarchar(15),
@Identity int OUT
AS
INSERT INTO Categories (CategoryName) VALUES(@CategoryName)
SET @Identity = SCOPE_IDENTITY()
Następnie procedurę składowaną można określić jako źródło obiektu InsertCommandSqlDataAdapter. Właściwość CommandTypeInsertCommand musi być ustawiona na StoredProcedure. Dane wyjściowe tożsamości są pobierane przez utworzenie obiektu SqlParameter z wartością ParameterDirectionOutput. Po przetworzeniu InsertCommand obiektu zwracana jest automatycznie zwiększana wartość tożsamości i umieszczana w kolumnie CategoryID bieżącego wiersza, jeśli ustawisz UpdatedRowSource właściwość polecenia insert na UpdateRowSource.OutputParameters lub na UpdateRowSource.Both.
Jeśli polecenie insert wykonuje partię zawierającą zarówno instrukcję INSERT, jak i instrukcję SELECT zwracającą nową wartość tożsamości, to możesz pobrać nową wartość, ustawiając właściwość UpdatedRowSource polecenia insert na wartość 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]);
}
}
}
}
Scalanie nowych wartości tożsamości
Typowym scenariuszem jest wywołanie metody GetChanges z DataTable, aby utworzyć kopię zawierającą tylko zmienione wiersze, i użycie nowej kopii podczas wywoływania metody UpdateDataAdapter. Jest to szczególnie przydatne, gdy konieczne jest przeprowadzenie marshalingu zmienionych wierszy do oddzielnego składnika wykonującego aktualizację. Po aktualizacji kopia może zawierać nowe wartości tożsamości, które należy następnie scalić z powrotem w oryginalny element DataTable. Nowe wartości tożsamości mogą się różnić od oryginalnych wartości w pliku DataTable. Aby móc wykonać scalanie, oryginalne wartości kolumn AutoInkrement w kopii powinny zostać zachowane, co umożliwi zlokalizowanie i zaktualizowanie istniejących wierszy w oryginalnym obiekcie DataTable zamiast dołączania nowych wierszy zawierających nowe wartości identyfikatorów. Jednak domyślnie te oryginalne wartości są tracone po wywołaniu metody Update dla DataAdapter, ponieważ AcceptChanges jest niejawnie wywoływana dla każdego zaktualizowanego DataRow.
Istnieją dwa sposoby zachowania oryginalnych wartości DataColumn w DataRow podczas aktualizacji DataAdapter:
Pierwszą metodą zachowania oryginalnych wartości jest ustawienie właściwości
AcceptChangesDuringUpdatedlaDataAdapternafalse. Ta konfiguracja ma wpływ na każdyDataRoww aktualizowanymDataTable. Aby uzyskać więcej informacji i przykładowy kod, zobacz AcceptChangesDuringUpdate.Drugą metodą jest napisanie kodu w procedurze
RowUpdatedobsługi zdarzeń obiektu , aby ustawić wartośćDataAdapterStatus.SkipCurrentRow ElementDataRowjest aktualizowany, ale oryginalna wartość każdegoDataColumnjest zachowywana. Ta metoda umożliwia zachowanie oryginalnych wartości dla niektórych wierszy, natomiast nie dla innych. Na przykład, Twój kod może zachować oryginalne wartości dla dodanych wierszy, a nie dla edytowanych lub usuniętych wierszy, najpierw sprawdzając StatementType, a następnie ustawiając Status na SkipCurrentRow tylko dla wierszy zStatementTyperównymInsert.
Gdy którakolwiek z tych metod jest używana do zachowania oryginalnych wartości w DataRow podczas aktualizacji DataAdapter, adapter danych Microsoft SqlClient dla programu SQL Server przeprowadza szereg działań, aby ustawić bieżące wartości DataRow na nowe wartości zwracane przez parametry wyjściowe lub przez pierwszy zwrócony wiersz zestawu wyników, zachowując jednocześnie oryginalną wartość w każdym elemencie DataColumn. Najpierw metoda AcceptChanges jest wywoływana w celu zachowania bieżących wartości jako oryginalnych, a następnie przypisywane są nowe wartości. Po wykonaniu tych akcji, DataRows z właściwością RowState, której wartość została ustawiona na Added, będą miały właściwość RowState ustawioną na Modified, co może być nieoczekiwane.
Sposób stosowania wyników polecenia do każdego aktualizowanego DataRow jest określany przez właściwość UpdatedRowSource każdego DbCommand elementu. Ta właściwość jest ustawiona na wartość z UpdateRowSource wyliczenia.
W poniższej tabeli opisano, w jaki sposób wartości wyliczenia UpdateRowSource wpływają na właściwość RowState zaktualizowanych wierszy.
| Nazwa członka | Description |
|---|---|
| Both |
AcceptChanges jest wywoływane, a wartości parametrów wyjściowych i/lub wartości z pierwszego wiersza dowolnego zwróconego zestawu wyników są umieszczane w DataRow podczas aktualizacji. Jeśli nie ma żadnych wartości do zastosowania, RowState będzie Unchanged. |
| FirstReturnedRecord | Jeśli wiersz został zwrócony, wywoływany jest AcceptChanges, a wiersz jest mapowany na zmieniony wiersz w elemencie DataTable, ustawiając RowState na Modified. Jeśli żaden wiersz nie jest zwracany, AcceptChanges nie jest wywoływany i RowState pozostaje Added. |
| None | Wszystkie zwrócone parametry lub wiersze są ignorowane. Nie ma połączenia z AcceptChanges, a RowState pozostaje Added. |
| OutputParameters |
AcceptChanges jest wywoływany, a wszystkie parametry wyjściowe są mapowane na zmieniony wiersz w obiekcie DataTable, ustawiając RowState na Modified. Jeśli nie ma parametrów wyjściowych, RowState będzie to Unchanged. |
Example
W tym przykładzie pokazano wyodrębnianie zmienionych wierszy z elementu DataTable i wykorzystanie SqlDataAdapter w celu zaktualizowania źródła danych oraz pobrania nowego identyfikatora kolumny.
InsertCommand wykonuje dwie instrukcje Transact-SQL: pierwsza to instrukcja INSERT, a druga to instrukcja SELECT, która używa funkcji SCOPE_IDENTITY do pobrania wartości identyfikatora.
INSERT INTO dbo.Shippers (CompanyName)
VALUES (@CompanyName);
SELECT ShipperID, CompanyName FROM dbo.Shippers
WHERE ShipperID = SCOPE_IDENTITY();
Właściwość UpdatedRowSource polecenia insert jest ustawiona na UpdateRowSource.FirstReturnedRow, a właściwość MissingSchemaActionDataAdapter jest ustawiona na MissingSchemaAction.AddWithKey. Element DataTable jest wypełniony, a kod dodaje nowy wiersz do elementu DataTable. Zmienione wiersze są następnie wyodrębniane do nowego DataTable, który jest przekazywany do DataAdapter, co następnie aktualizuje serwer.
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]);
}
}
}
}
Procedura OnRowUpdated obsługi zdarzeń sprawdza element StatementType , SqlRowUpdatedEventArgs aby określić, czy wiersz jest wstawiany. Jeśli tak jest, właściwość Status jest ustawiona na SkipCurrentRow. Wiersz jest aktualizowany, ale oryginalne wartości w wierszu są zachowywane. W głównym korpusie procedury wywoływana jest metoda Merge w celu scalenia nowej wartości tożsamości z oryginalną wartością DataTable, a na koniec wywoływana jest 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;
}
}
Pobieranie wartości tożsamości
Często ustawiamy kolumnę jako tożsamość, gdy wartości w kolumnie muszą być unikatowe. Czasami potrzebujemy wartości tożsamości nowych danych. W tym przykładzie pokazano, jak pobrać wartości tożsamości:
Tworzy procedurę składowaną w celu wstawiania danych i zwracania wartości identyfikatora.
Wykonuje polecenie , aby wstawić nowe dane i wyświetlić wynik.
Używa SqlDataAdapter metody do wstawiania nowych danych i wyświetlania wyniku.
Przed skompilowaniem i uruchomieniem przykładowego programu należy utworzyć przykładową bazę danych, używając następującego skryptu:
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
Lista kodu jest następująca:
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();
}
}