I have old legacy MVC app that uses Identity 2.0. Also recently I have created .Net 6 API with Identity 6.0 (AspNetCore.Identity.EntityFrameworkCore).
Note: There are some schema related changes in both of this framework, like some additional tables and fields. check snapshot that I added at last.
The issue is the common database that I have to manage.
I have tried and successfully completed updation of existing database with latest schema.
I have also migrated the data for the identity tables.
The only issue I face right now is I'm not sure how to support old legacy app going further. (I want to have old app as it is, but want it to use new identity tables.)
Since the exisiting/old app is in .Net framework 4.6.1, I can not really update identity and it's tables to have latest schema in it. (I don't mind doing any hack or any fix. old app should work with latest idenitty schema is what imp for me at the moment.)
Is there any option that I can follow without changing code much, I have tight deadline to follow and I don't really want to create external API to authenticate old legacy app. Any help or idea would be really appreciated.
I didn't find any way to update existing app (.Net standard 4.6) to support new identity structure. So here is what I did to resolve this issue.
As #Jeremy suggested in comments, I configured my .Net core Identity models to have different names (other then by default, so it does not have any conflict with existing tables) https://learn.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-6.0#change-tablecolumn-names-and-facets (keep order of model configuration as it is as given in thread. I got issues when I kept my base.OnModelCreating(builder); below builder configuration.)
I have found a script to create identity tables schema and move records. see below screenshot. _New represents the .Net core identity tables scehma. I have attached that script here with and I have run this script in common database.
So now I have common database with both old and new identity tables. old application is still pointing and working well with old tables which .Net core identity framework is poiting to new database.
Since I have moved all the data and records from old tables to new table, I can access them in new idenity app too.
Till now I have no need to run migration in new app, so I disabled it. but there was concern of what if I run migration and how will it affect existing database. so I did some R&D and found that we can create migration and before running that migration, we can just comment out the code inside the up and down method. after that we can run this migration and update database. basically empty migration to keep in sync with existing database. (haven't checked this working but this was my idea if I needed it)
Here is the sql Script that I used.
STEP 1 : Change name of existing tables
EXEC sp_rename 'AspNetRoles', 'AspNetRoles_old';
EXEC sp_rename 'AspNetUserClaims', 'AspNetUserClaims_old';
EXEC sp_rename 'AspNetUserLogins', 'AspNetUserLogins_old';
EXEC sp_rename 'AspNetUserRoles', 'AspNetUserRoles_old';
EXEC sp_rename 'AspNetUsers', 'AspNetUsers_old';
STEP 2 : Create ASP.NET Core Identity tables
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetRoleClaims](
[Id] [int] IDENTITY(1,1) NOT NULL,
[RoleId] [nvarchar](450) NOT NULL,
[ClaimType] [nvarchar](max) NULL,
[ClaimValue] [nvarchar](max) NULL,
CONSTRAINT [PK_AspNetRoleClaims] PRIMARY KEY CLUSTERED
(
[Id] 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].[AspNetRoles](
[Id] [nvarchar](450) NOT NULL,
[Name] [nvarchar](256) NULL,
[NormalizedName] [nvarchar](256) NULL,
[ConcurrencyStamp] [nvarchar](max) NULL,
CONSTRAINT [PK_AspNetRoles] PRIMARY KEY CLUSTERED
(
[Id] 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].[AspNetUserClaims](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [nvarchar](450) NOT NULL,
[ClaimType] [nvarchar](max) NULL,
[ClaimValue] [nvarchar](max) NULL,
CONSTRAINT [PK_AspNetUserClaims] PRIMARY KEY CLUSTERED
(
[Id] 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].[AspNetUserLogins](
[LoginProvider] [nvarchar](128) NOT NULL,
[ProviderKey] [nvarchar](128) NOT NULL,
[ProviderDisplayName] [nvarchar](max) NULL,
[UserId] [nvarchar](450) NOT NULL,
CONSTRAINT [PK_AspNetUserLogins] PRIMARY KEY CLUSTERED
(
[LoginProvider] ASC,
[ProviderKey] 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].[AspNetUserRoles](
[UserId] [nvarchar](450) NOT NULL,
[RoleId] [nvarchar](450) NOT NULL,
CONSTRAINT [PK_AspNetUserRoles] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[RoleId] 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].[AspNetUsers](
[Id] [nvarchar](450) NOT NULL,
[UserName] [nvarchar](256) NULL,
[NormalizedUserName] [nvarchar](256) NULL,
[Email] [nvarchar](256) NULL,
[NormalizedEmail] [nvarchar](256) NULL,
[EmailConfirmed] [bit] NOT NULL,
[PasswordHash] [nvarchar](max) NULL,
[SecurityStamp] [nvarchar](max) NULL,
[ConcurrencyStamp] [nvarchar](max) NULL,
[PhoneNumber] [nvarchar](max) NULL,
[PhoneNumberConfirmed] [bit] NOT NULL,
[TwoFactorEnabled] [bit] NOT NULL,
[LockoutEnd] [datetimeoffset](7) NULL,
[LockoutEnabled] [bit] NOT NULL,
[AccessFailedCount] [int] NOT NULL,
CONSTRAINT [PK_AspNetUsers] PRIMARY KEY CLUSTERED
(
[Id] 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].[AspNetUserTokens](
[UserId] [nvarchar](450) NOT NULL,
[LoginProvider] [nvarchar](128) NOT NULL,
[Name] [nvarchar](128) NOT NULL,
[Value] [nvarchar](max) NULL,
CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[LoginProvider] ASC,
[Name] 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_PADDING ON
GO
CREATE NONCLUSTERED INDEX [IX_AspNetRoleClaims_RoleId] ON [dbo].[AspNetRoleClaims]
(
[RoleId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
CREATE UNIQUE NONCLUSTERED INDEX [RoleNameIndex] ON [dbo].[AspNetRoles]
(
[NormalizedName] ASC
)
WHERE ([NormalizedName] IS NOT NULL)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
CREATE NONCLUSTERED INDEX [IX_AspNetUserClaims_UserId] ON [dbo].[AspNetUserClaims]
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
CREATE NONCLUSTERED INDEX [IX_AspNetUserLogins_UserId] ON [dbo].[AspNetUserLogins]
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
CREATE NONCLUSTERED INDEX [IX_AspNetUserRoles_RoleId] ON [dbo].[AspNetUserRoles]
(
[RoleId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
CREATE NONCLUSTERED INDEX [EmailIndex] ON [dbo].[AspNetUsers]
(
[NormalizedEmail] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
CREATE UNIQUE NONCLUSTERED INDEX [UserNameIndex] ON [dbo].[AspNetUsers]
(
[NormalizedUserName] ASC
)
WHERE ([NormalizedUserName] IS NOT NULL)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[AspNetRoleClaims] WITH CHECK ADD CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId] FOREIGN KEY([RoleId])
REFERENCES [dbo].[AspNetRoles] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetRoleClaims] CHECK CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId]
GO
ALTER TABLE [dbo].[AspNetUserClaims] WITH CHECK ADD CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserClaims] CHECK CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId]
GO
ALTER TABLE [dbo].[AspNetUserLogins] WITH CHECK ADD CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserLogins] CHECK CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId]
GO
ALTER TABLE [dbo].[AspNetUserRoles] WITH CHECK ADD CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId] FOREIGN KEY([RoleId])
REFERENCES [dbo].[AspNetRoles] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserRoles] CHECK CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId]
GO
ALTER TABLE [dbo].[AspNetUserRoles] WITH CHECK ADD CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserRoles] CHECK CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId]
GO
ALTER TABLE [dbo].[AspNetUserTokens] WITH CHECK ADD CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserTokens] CHECK CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId]
GO
STEP 3 : Migrate data from old tables (ASP.NET Identity) to new tables (ASP.NET Core Identity)
INSERT INTO AspNetRoles ([Id], [Name], [NormalizedName], [ConcurrencyStamp])
SELECT [Id], [Name], UPPER([Name]), LOWER(NEWID()) FROM Objectra_Development.dbo.AspNetRoles
INSERT INTO AspNetUsers ([Id], [UserName], [NormalizedUserName], [Email], [NormalizedEmail], [EmailConfirmed], [PasswordHash], [SecurityStamp], [ConcurrencyStamp], [PhoneNumber], [PhoneNumberConfirmed], [TwoFactorEnabled], [LockoutEnd], [LockoutEnabled], [AccessFailedCount],
AssignObjects, AccessOwnObjectsOnly, UserObjectId, UserObjectDefd, GoogleAuth, LastPasswordResetDate, FriendlyName, AccessibleObjectDefinitions)
SELECT [Id], [UserName], UPPER([UserName]), [Email], UPPER([Email]), [EmailConfirmed], [PasswordHash], [SecurityStamp], LOWER(NEWID()), [PhoneNumber], [PhoneNumberConfirmed], 0, null, 1, 0,
AssignObjects, AccessOwnObjectsOnly, UserObjectId, UserObjectDefd, GoogleAuth, LastPasswordResetDate, FriendlyName, AccessibleObjectDefinitions
FROM Objectra_Development.dbo.AspNetUsers;
INSERT INTO AspNetUserRoles ([UserId], [RoleId])
SELECT [UserId], [RoleId]
FROM Objectra_Development.dbo.AspNetUserRoles;
I faced the same problem and ended up creating new identity core tables using a schema.
builder.ToTable(name: "Users", "Identity");
builder.ToTable(name: "Roles", "Identity");
builder.ToTable(name: "UserRoles", "Identity");
builder.ToTable(name: "UserClaims", "Identity");
builder.ToTable(name: "UserLogins", "Identity");
builder.ToTable(name: "UserTokens", "Identity");
builder.ToTable(name: "RoleClaims", "Identity");
Then I used a trigger on the old identity users table to keep the new identity users table in sync.
CREATE/*ALTER*/ TRIGGER [dbo].[IdentityUsers_Sync] ON [dbo].[Users]
AFTER INSERT, UPDATE AS
BEGIN
--INSERT
IF NOT EXISTS (SELECT * FROM deleted)
BEGIN
INSERT INTO [Identity].[Users]
(
Id,
UserName,
NormalizedUserName,
Email,
NormalizedEmail,
EmailConfirmed,
PasswordHash,
SecurityStamp,
PhoneNumber,
PhoneNumberConfirmed,
TwoFactorEnabled,
LockoutEnabled,
AccessFailedCount
)
SELECT
Id,
UserName,
UPPER(UserName),
Email,
UPPER(Email),
EmailConfirmed,
PasswordHash,
SecurityStamp,
PhoneNumber,
PhoneNumberConfirmed,
TwoFactorEnabled,
0,
0
FROM inserted
END
--UPDATE
IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
BEGIN
UPDATE iu
SET
iu.UserName = i.UserName,
iu.NormalizedUserName = UPPER(i.UserName),
iu.Email = i.Email,
iu.NormalizedEmail = UPPER(i.Email),
iu.EmailConfirmed = i.EmailConfirmed,
iu.PasswordHash = i.PasswordHash,
iu.SecurityStamp = i.SecurityStamp,
iu.PhoneNumber = i.PhoneNumber,
iu.PhoneNumberConfirmed = i.PhoneNumberConfirmed,
iu.TwoFactorEnabled = i.TwoFactorEnabled,
iu.LockoutEnabled = 0,
iu.AccessFailedCount = 0
FROM [Identity].[Users] iu, inserted i
WHERE iu.Id = i.Id
END
END
GO
ALTER TABLE [dbo].[Users] ENABLE TRIGGER [IdentityUsers_Sync]
GO
And my plan is to create an api controller in the legacy system to handle new registrations (via HttpClient in any new Core apps). Then the trigger will pick it up and keep the new system in sync.
Having the legacy system use the new identity tables doesn't look like an option at this point. Maybe additional fields could be added to the new schema and use a trigger to fill them in? Haven't tried that.
I am trying to develop a inventory management system. But problem is when i am going to stock in my stock table then these product quantities are need to need update in item table at a time. As a example, I am going to increase stock 100s of products in stock table when i will press save button all of the products which of them are status='Posting' will be updated with tbl_item.quantity+tbl_stock.qty in according to itemcode. Please help me...
Here is my table where i am increasing stock.
CREATE TABLE [dbo].[tbl_Addstock](
[id] [int] IDENTITY(1,1) NOT NULL,
[ItemCode] [varchar](50) NOT NULL,
[ItemName] [varchar](250) NOT NULL,
[qty] [decimal](18, 2) NOT NULL,
[sdate] [date] NOT NULL,
[sadmin] [varchar](50) NOT NULL,
[Status] [varchar](50) NULL,
CONSTRAINT [PK_tbl_Addstock] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Here is my another item table where i want to update my total stock information.
CREATE TABLE [dbo].[tbl_Item](
[id] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](50) NOT NULL,
[batchno] [nvarchar](50) NOT NULL,
[brand] [nvarchar](50) NOT NULL,
[itemcode] [varchar](50) NOT NULL,
[catg] [nvarchar](50) NOT NULL,
[supplier] [nvarchar](50) NULL,
[unitType] [nvarchar](50) NOT NULL,
[Quantity] [decimal](18, 2) NULL,
[buyingPrice] [money] NULL,
[sellingPrice] [money] NULL,
[qtyLimit] [int] NULL,
[vat] [decimal](18, 2) NULL,
CONSTRAINT [PK_tbl_Item] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Then I have tried a cursor query..
USE [NMCPMC]
GO
/****** Object: StoredProcedure [dbo].[sp_UpdateItem] Script Date: 01/07/2015 12:41:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--exec sp_UpdateItem
ALTER PROCEDURE [dbo].[sp_UpdateItem]
AS
BEGIN
SET NOCOUNT ON
DECLARE
#TEMP AS VARCHAR(50), #ItemCode varchar(20),
#eqty decimal(18,2)
DECLARE ITEM_CURSOR CURSOR FOR
SELECT ItemCode,qty FROM tbl_Addstock
OPEN ITEM_CURSOR
FETCH NEXT FROM ITEM_CURSOR
INTO #ItemCode,#TEMP
WHILE (##FETCH_STATUS = 0)
BEGIN
--set #eqty = (select Quantity from tbl_Item)
-- SELECT #TEMP = SUM(ti.Quantity+ta.qty) from tbl_Addstock ta inner join tbl_Item ti on ta.ItemCode=ti.itemcode
-- UPDATE tbl_Item SET Quantity = #TEMP WHERE CURRENT OF ITEM_CURSOR
if exists(select * from tbl_Addstock where ItemCode=#ItemCode)
begin
UPDATE tbl_Addstock SET qty = qty+#TEMP WHERE ItemCode=#ItemCode
update tbl_Addstock set qty=qty-#TEMP WHERE ItemCode=#ItemCode
end
else
begin
-- insert into tbl_Addstock
update tbl_Addstock set qty=qty-#TEMP WHERE ItemCode=#ItemCode
end
print #ItemCode
print #TEMP
FETCH NEXT FROM ITEM_CURSOR
INTO #ItemCode,#TEMP
END
CLOSE ITEM_CURSOR
DEALLOCATE ITEM_CURSOR
SET NOCOUNT OFF
END
--EXEC sp_UpdateItem
So you want to add to the tbl_Item the quantity expressed in your tbl_AddStock.
Your SP doesn't seem to work correctly because you never touch the quantuty field of the table tbl_Item.
I would write instead
ALTER PROCEDURE [dbo].[sp_UpdateItem]
AS
BEGIN
SET NOCOUNT ON
DECLARE
#ItemCode varchar(20),
#eqty decimal(18,2)
DECLARE ITEM_CURSOR CURSOR FOR
SELECT ItemCode,qty FROM tbl_Addstock WHERE Status = 'Posting'
OPEN ITEM_CURSOR
FETCH NEXT FROM ITEM_CURSOR
INTO #ItemCode,#eqty
WHILE (##FETCH_STATUS = 0)
BEGIN
if exists(select * from tbl_Item where ItemCode=#ItemCode)
begin
UPDATE tbl_Item SET quantity = quantity + #eqty WHERE ItemCode=#ItemCode
UPDATE tbl_Addstock SET qty = qty - #eqty, Status = 'Posted' WHERE ItemCode=#ItemCode
-- COULD AVOID THE MATH. SIMPLY SET QTY=0
-- ? UPDATE tbl_Addstock SET qty = 0 WHERE ItemCode=#ItemCode
end
else
begin
-- THIS ELSE PART IS WHERE YOU DISCOVER THAT tbl_Item
-- HAD NO RECORD FOR THE #ItemCode.
-- YOU SHOULD ADD THE NEW ITEM TO THE tblItem TABLE
-- BUT MANY FIELDS OF THAT TABLE ARE NOT NULL (batchno, catg, brand, unittype)
-- SO YOU NEED TO KNOW THE VALUES FOR THESE
-- FIELDS OTHERWISE YOU WONT BE ABLE TO ADD ANYTHING
-- ??? -> INSERT INTO tbl_Item(ItemCode, Qty) VALUES (#itemcode, #eqty)
end
FETCH NEXT FROM ITEM_CURSOR
INTO #ItemCode,#qty
END
CLOSE ITEM_CURSOR
DEALLOCATE ITEM_CURSOR
SET NOCOUNT OFF
END
please check it this two tables.
create table Panda (id int identity, koalaId null)
create table Koala (id int identity)
I need that koalaId was foreign key to table Koala -> identity, but also I need that koalaId can be a NULL.
After this will be resolved, I need get data from Panda, but I get only a error:
Property koalaId for Panda not be set to null. This property must be set to a value that is not null and is of type Int32.
And I want for koalaId set to null.
Thank you for your advice.
By default a foreign key column will allow null value. you don't want to mention it explicitly.
**for example:**
Create table Kola(Id numeric identity(1,1) primary key)
Create table Panda(Id numeric identity(1,1),
KolaId numeric references Kola(Id))
*Note:*But make sure column 'id' in table 'kola' should be a primary key before it get referenced
by another table.
here is Panda and Cola creation codes:
CREATE TABLE [dbo].[Kola](
[id] [int] NOT NULL,
[kolaName] [nchar](10) NULL,
CONSTRAINT [PK_Kola] PRIMARY KEY CLUSTERED
(
[id] 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
CREATE TABLE [dbo].[Panda](
[id] [int] NOT NULL,
[KolaId] [int] NULL,
CONSTRAINT [PK_Panda] PRIMARY KEY CLUSTERED
(
[id] 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
ALTER TABLE [dbo].[Panda] WITH CHECK ADD CONSTRAINT [FK_Panda_Kola] FOREIGN KEY([KolaId])
REFERENCES [dbo].[Kola] ([id])
GO
ALTER TABLE [dbo].[Panda] CHECK CONSTRAINT [FK_Panda_Kola]
GO