Please find all the necessary scripts at the bottom of this post to create the scenario I'm describing here.
Scenario:
I have a "Transactions" table where I store all transactions in a stock market management app. ALL transactions are in there with the pertinent info e.g. TransactionType, TransactionAmount, etc.
The next two tables are super simple and self explanatory i.e. People and Companies.
I then have a table called TransactionsForCompanies where I store all transactions created by corporate customers. In this table, I have only two columns: TransactionId -- coming from the Transactions table -- CompanyId -- coming from the Companies table.
The next table called TransactionsForPeople is almost identical the last one but it's used for identifying transactions created by individuals.
Please see the DB structure and I think it'll make sense fairly easily.
Here's what I'm trying to do and where I need help.
I want to create a view that gives me the "Last Transaction Date" for people. So if a person had multiple transactions in the last month, this view is supposed to give me the last transaction date for that individual who might have had the transaction only 2 hours ago. Of course, the view will return last transaction date for ALL "individual customers".
To do this, I used the MAX function and the view worked nicely. However, because I'm using the MAX function, I cannot create an index for the view. As a result, I have a performance issue because my "Transactions" table has millions of records.
Of course the idea is to use the view in another SELECT statement so that I can generate nice reports about most and least active clients. This SELECT statement runs very slowly and when I look at the execution plan, the bottleneck is where I have my JOIN to the view that is using the MAX function.
QUESTION: How do I capture the last TransactionDate for people who had transactions in a way that gives me good performance?
Thanks...
USE [TestDb]
GO
/****** Object: Table [dbo].[Companies] Script Date: 4/7/2013 1:48:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Companies](
[CompanyId] [int] IDENTITY(1,1) NOT NULL,
[CompanyName] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Companies] PRIMARY KEY CLUSTERED
(
[CompanyId] 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
/****** Object: Table [dbo].[People] Script Date: 4/7/2013 1:48:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[People](
[PersonId] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](20) NOT NULL,
[MiddleName] [nvarchar](20) NULL,
[LastName] [nvarchar](20) NOT NULL,
CONSTRAINT [PK_People] 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]
GO
/****** Object: Table [dbo].[Transactions] Script Date: 4/7/2013 1:48:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Transactions](
[TransactionId] [int] IDENTITY(1,1) NOT NULL,
[TransactionType] [nvarchar](50) NOT NULL,
[TransactionTimeStamp] [datetime] NOT NULL,
[TransactionAmount] [money] NOT NULL,
[Comments] [nvarchar](50) NULL,
CONSTRAINT [PK_Transactions] PRIMARY KEY CLUSTERED
(
[TransactionId] 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
/****** Object: Table [dbo].[TransactionsForCompanies] Script Date: 4/7/2013 1:48:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TransactionsForCompanies](
[TransactionId] [int] NOT NULL,
[CompanyId] [int] NOT NULL,
CONSTRAINT [PK_TransactionsForCompanies] PRIMARY KEY CLUSTERED
(
[TransactionId] ASC,
[CompanyId] 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
/****** Object: Table [dbo].[TransactionsForPeople] Script Date: 4/7/2013 1:48:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TransactionsForPeople](
[TransactionId] [int] NOT NULL,
[PersonId] [int] NOT NULL,
CONSTRAINT [PK_TransactionsForPeople] PRIMARY KEY CLUSTERED
(
[TransactionId] ASC,
[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]
GO
SET IDENTITY_INSERT [dbo].[Companies] ON
GO
INSERT [dbo].[Companies] ([CompanyId], [CompanyName]) VALUES (1, N'Company A')
GO
INSERT [dbo].[Companies] ([CompanyId], [CompanyName]) VALUES (2, N'Company B')
GO
INSERT [dbo].[Companies] ([CompanyId], [CompanyName]) VALUES (3, N'Company C')
GO
SET IDENTITY_INSERT [dbo].[Companies] OFF
GO
SET IDENTITY_INSERT [dbo].[People] ON
GO
INSERT [dbo].[People] ([PersonId], [FirstName], [MiddleName], [LastName]) VALUES (1, N'John', NULL, N'Doe')
GO
INSERT [dbo].[People] ([PersonId], [FirstName], [MiddleName], [LastName]) VALUES (2, N'Jane', NULL, N'Smith')
GO
INSERT [dbo].[People] ([PersonId], [FirstName], [MiddleName], [LastName]) VALUES (3, N'Betsy', NULL, N'Green')
GO
SET IDENTITY_INSERT [dbo].[People] OFF
GO
SET IDENTITY_INSERT [dbo].[Transactions] ON
GO
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (1, N'BUY', CAST(0x0000A1990122F5C4 AS DateTime), 300.0000, N'Got it!')
GO
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (2, N'BID', CAST(0x0000A19901236069 AS DateTime), 1753.5000, N'My best offer...')
GO
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (3, N'SELL', CAST(0x0000A19901236AF5 AS DateTime), 1753.5000, N'Will take it!')
GO
INSERT [dbo].[Transactions] ([TransactionId], [TransactionType], [TransactionTimeStamp], [TransactionAmount], [Comments]) VALUES (4, N'BUY', CAST(0x0000A19901236C21 AS DateTime), 1753.5000, N'Finalize purchase.')
GO
SET IDENTITY_INSERT [dbo].[Transactions] OFF
GO
INSERT [dbo].[TransactionsForCompanies] ([TransactionId], [CompanyId]) VALUES (3, 1)
GO
INSERT [dbo].[TransactionsForPeople] ([TransactionId], [PersonId]) VALUES (1, 2)
GO
INSERT [dbo].[TransactionsForPeople] ([TransactionId], [PersonId]) VALUES (2, 3)
GO
INSERT [dbo].[TransactionsForPeople] ([TransactionId], [PersonId]) VALUES (4, 3)
GO
ALTER TABLE [dbo].[Transactions] ADD CONSTRAINT [DF_Transactions_TransactionTimeStamp] DEFAULT (getutcdate()) FOR [TransactionTimeStamp]
GO
ALTER TABLE [dbo].[TransactionsForCompanies] WITH CHECK ADD CONSTRAINT [FK_TransactionsForCompanies_Companies] FOREIGN KEY([CompanyId])
REFERENCES [dbo].[Companies] ([CompanyId])
GO
ALTER TABLE [dbo].[TransactionsForCompanies] CHECK CONSTRAINT [FK_TransactionsForCompanies_Companies]
GO
ALTER TABLE [dbo].[TransactionsForCompanies] WITH CHECK ADD CONSTRAINT [FK_TransactionsForCompanies_Transactions] FOREIGN KEY([TransactionId])
REFERENCES [dbo].[Transactions] ([TransactionId])
GO
ALTER TABLE [dbo].[TransactionsForCompanies] CHECK CONSTRAINT [FK_TransactionsForCompanies_Transactions]
GO
ALTER TABLE [dbo].[TransactionsForPeople] WITH CHECK ADD CONSTRAINT [FK_TransactionsForPeople_People] FOREIGN KEY([PersonId])
REFERENCES [dbo].[People] ([PersonId])
GO
ALTER TABLE [dbo].[TransactionsForPeople] CHECK CONSTRAINT [FK_TransactionsForPeople_People]
GO
ALTER TABLE [dbo].[TransactionsForPeople] WITH CHECK ADD CONSTRAINT [FK_TransactionsForPeople_Transactions] FOREIGN KEY([TransactionId])
REFERENCES [dbo].[Transactions] ([TransactionId])
GO
ALTER TABLE [dbo].[TransactionsForPeople] CHECK CONSTRAINT [FK_TransactionsForPeople_Transactions]
GO
Your not going to be able to create an indexed view if you want to use max(), as you have said.
How about either:
(i) Changing the primary key to be nonclustered, and then adding a clustered index on TransactionTimestamp for the Transactions table?
(ii) Adding an index on TransactionId, TransactionTimestamp on the Transactions table.
Related
I have a table of "CASH PAYMENT". I created two tables in SQL Server 2008 and did drag and drop in vb.net 2010.
Now when I save it with default update code, I get different errors.
I do not have any idea of relationships. I searched the web about it but did not find anything related to it. Also, what code can I use to update my relationship entry for vb.net using SQL Server?
I tried nothing - I only drag and drop the SQL Server database in vb.net and with default update code I got error:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_cash-entries_cash-entries". The conflict occurred in database "dbo_main", table "dbo.cash_payn_details", column 'autonumber'
Code is shown below. This is the default code when drag drop SQL Server in vb.net
Me.Validate()
Me.Cash_payn_detailsBindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.Dbo_mainDataSet)
Me.Cash_entriesBindingSource.EndEdit()
Me.Cash_entriesTableAdapter.Update(Me.Dbo_mainDataSet)
I want to save two tables with one reference number. I am a beginner in vb.net and SQL Server relationships.
Edit
Table structure:
USE [dbo_main]
GO
/****** Object: Table [dbo].[cash_payn_details] Script Date: 01/04/2019 17:44:25 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[cash_payn_details](
[autonumber] [nchar](10) NOT NULL,
[account] [nchar](10) NULL,
[amount] [nchar](10) NULL,
[date] [nchar](10) NULL,
CONSTRAINT [PK_cash_payn_details] PRIMARY KEY CLUSTERED
(
[autonumber] 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
OTHER IS
USE [dbo_main]
GO
/****** Object: Table [dbo].[cash-entries] Script Date: 01/04/2019 17:45:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[cash-entries](
[des_autonumber] [nchar](10) NOT NULL,
[system_ID] [nchar](10) NULL,
[entries] [nvarchar](50) NULL,
CONSTRAINT [PK_cash-entries] PRIMARY KEY CLUSTERED
(
[des_autonumber] 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].[cash-entries] WITH CHECK ADD CONSTRAINT [FK_cash-entries_cash-entries] FOREIGN KEY([system_ID])
REFERENCES [dbo].[cash_payn_details] ([autonumber])
GO
ALTER TABLE [dbo].[cash-entries] CHECK CONSTRAINT [FK_cash-entries_cash-entries]
GO
INSERT INTO [dbo_main].[dbo].[cash-entries]
([des_autonumber]
,[system_ID]
,[entries])
VALUES
(<des_autonumber, nchar(10),>
,<system_ID, nchar(10),>
,<entries, nvarchar(50),>)
GO
other is
INSERT INTO [dbo_main].[dbo].[cash_payn_details]
([autonumber]
,[account]
,[amount]
,[date])
VALUES
(<autonumber, nchar(10),>
,<account, nchar(10),>
,<amount, nchar(10),>
,<date, nchar(10),>)
GO
Im trying to use Linqpad so as to use LINQ instead of TSQL when trying to remove some records from a table that is part of a "dependency tree" that spans probably 10-12 tables. So I created some tables in a test db and im experimenting with the DeleteAllOnSubmit and SubmitChanges methods.
I get an FK error. Yet, Im deleting the child objects first. How do I delete when there is FK relations (without using cascading on the FK's)?
The DELETE statement conflicted with the REFERENCE constraint
"FK_OrderItem_Order". The conflict occurred in database "Test", table
"dbo.OrderItem", c...
Tables:
USE [Test]
GO
/****** Object: Table [dbo].[Order] Script Date: 6/9/2016 2:50:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Order](
[Id] [int] IDENTITY(1,1) NOT NULL,
[OrderNum] [varchar](20) NOT NULL,
[Description] [varchar](100) NULL,
CONSTRAINT [PK_Order] 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
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[OrderItem] Script Date: 6/9/2016 2:50:18 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[OrderItem](
[Id] [int] IDENTITY(1,1) NOT NULL,
[OrderId] [int] NOT NULL,
[OrderItemName] [varchar](100) NOT NULL,
[Qty] [int] NOT NULL,
CONSTRAINT [PK_OrderItem] 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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[OrderItem] WITH CHECK ADD CONSTRAINT [FK_OrderItem_Order] FOREIGN KEY([OrderId])
REFERENCES [dbo].[Order] ([Id])
GO
ALTER TABLE [dbo].[OrderItem] CHECK CONSTRAINT [FK_OrderItem_Order]
GO
Here is my LINQ statement
List<Order> olist = (from a in Orders where a.Id == 2 select a).ToList();
List<int> olistidlist = olist.Select (o => o.Id).ToList();
List<OrderItem> oilist = (from a in OrderItems where olistidlist.Contains(a.Id) select a).ToList();
//see results before
olist.Dump();
OrderItems.DeleteAllOnSubmit(oilist);
Orders.DeleteAllOnSubmit(olist);
//save changes
SubmitChanges();
//see results after
olist.Dump();
You are deleting OrderItems of which the OrderItem.Id is equal to values in olistidlist (only 2, presently). Of course, this must be OrderItem.OrderId.
By the way, an easier way to delete parent and child items generally is:
foreach (var order in Orders.Where(...))
{
OrderItems.DeleteAllOnSubmit(order.OrderItems);
Orders.DeleteOnSubmit(order);
}
So you don't have to move around with Id values.
I'm aware that this question gets asked a million times, but I've already checked, double, and triple that corresponding values already exist in my parent table. I'm trying to populate a bridge table between my Albums and Artists, both of which are already populated. After getting errors in the C# program that was auto-populating, I tried inserting a single value manually, and still got the INSERT error.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Album](
[Album ID] [int] IDENTITY(1,1) NOT NULL,
[Album Title] [nchar](50) NOT NULL,
[Release Year] [int] NULL,
CONSTRAINT [PK_Album] PRIMARY KEY CLUSTERED
(
[Album 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
/****** Object: Table [dbo].[Album-Artists] Script Date: 3/6/2015 12:49:33 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Album-Artists](
[Album ID] [int] NOT NULL,
[Artist ID] [int] NOT NULL,
CONSTRAINT [PK_Album-Artists] PRIMARY KEY CLUSTERED
(
[Album ID] ASC,
[Artist 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
/****** Object: Table [dbo].[Artists] Script Date: 3/6/2015 12:49:33 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Artists](
[Artist ID] [int] IDENTITY(1,1) NOT NULL,
[Artists Name] [nchar](20) NOT NULL,
CONSTRAINT [PK_Artists] PRIMARY KEY CLUSTERED
(
[Artist 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
GO
ALTER TABLE [dbo].[Album-Artists] WITH CHECK ADD CONSTRAINT [FK_Album-Artists_Album] FOREIGN KEY([Album ID])
REFERENCES [dbo].[Album] ([Album ID])
GO
ALTER TABLE [dbo].[Album-Artists] CHECK CONSTRAINT [FK_Album-Artists_Album]
GO
ALTER TABLE [dbo].[Album-Artists] WITH CHECK ADD CONSTRAINT [FK_Album-Artists_Artists] FOREIGN KEY([Album ID])
REFERENCES [dbo].[Artists] ([Artist ID])
GO
ALTER TABLE [dbo].[Album-Artists] CHECK CONSTRAINT [FK_Album-Artists_Artists]
GO
(I've tried with and without the table quantifiers (Artists.[Artist ID], etc))
Your foreign key is trying to match ArtistId to AlbumId.
This is incorrect. You need to recreate it.
ALTER TABLE dbo.[Album-Artists]
DROP CONSTRAINT [FK_Album-Artists_Artists];
ALTER TABLE [dbo].[Album-Artists]
WITH CHECK ADD CONSTRAINT [FK_Album-Artists_Artists]
FOREIGN KEY([Artist ID]) REFERENCES [dbo].[Artists] ([Artist ID]);
Also the correct syntax for the insert is
INSERT INTO [dbo].[Album-Artists]
([Album ID], [Artist ID])
VALUES (10, 3);
Though dot-separated prefixes are currently ignored in the column list for INSERT statements.
Finally I would avoid using spaces or - in object names so you don't have to continually use quoted identifiers or square brackets and can use the unquoted form.
INSERT INTO dbo.AlbumArtists
(AlbumId, ArtistId)
VALUES (10, 3);
I've got two tables as per diagram below
here is sql script for USERS TABLES
USE [NewUser]
GO
/****** Object: Table [dbo].[USERS] Script Date: 15/12/2014 18:26:05 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[USERS](
[FirstName] [varchar](50) NULL,
[SureName] [varchar](50) NULL,
[DOB] [date] NULL,
[USID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_USERS] PRIMARY KEY CLUSTERED
(
[USID] 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_PADDING OFF
GO
And for ADDRESSES TABLE
USE [NewUser]
GO
/****** Object: Table [dbo].[ADDRESSES] Script Date: 15/12/2014 18:26:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[ADDRESSES](
[AID] [int] IDENTITY(1,1) NOT NULL,
[USID] [numeric](18, 0) NULL,
[AddressLine1] [varchar](50) NULL,
[AddressLine2] [varchar](50) NULL,
[PostCode] [varchar](50) NULL,
CONSTRAINT [PK_ADDRESSES] PRIMARY KEY CLUSTERED
(
[AID] 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_PADDING OFF
GO
ALTER TABLE [dbo].[ADDRESSES] WITH CHECK ADD CONSTRAINT [FK_ADDRESSES_USERS]
FOREIGN KEY([USID])
REFERENCES [dbo].[USERS] ([USID])
ON UPDATE CASCADE
ON DELETE SET NULL
GO
ALTER TABLE [dbo].[ADDRESSES] CHECK CONSTRAINT [FK_ADDRESSES_USERS]
GO
After that I have created a TRIGGER using
USE [NewUser]
GO
/****** Object: Trigger [dbo].[autoupdate] Script Date: 15/12/2014 18:33:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[autoupdate]
ON [dbo].[USERS]
AFTER INSERT, DELETE, UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #TEMPID INT
SET #TEMPID = (SELECT USID FROM INSERTED)
UPDATE ADDRESSES
SET USID = #TEMPID
END
The purpose of the TRIGGER is to insert UID automatically on the second table as soon as a new row is added or updated in first table.
But its not doing what I was expecting it to do.
Screenshots
USERS TABLE
ADDRESSES TABLE
USID from table USERS and AID from table ADDRESSES both has "Is Identity Set to YESS"
I'm assuming this is SQL Server, not MySql - please remove the conflicting RDBMS tag.
With triggers, you'll need to handle set data - the INSERTED and DELETED pseudocolumns are tables, not single rows.
Also, assuming that you aren't going to be updating the PK [USID] on Users, you won't need to handle an UPDATE in the trigger, just INSERT and DELETE, and it looks like you've already decided to handle deletes on user with ON DELETE SET NULL, which will set the USID foreign key to NULL in Addresses.
So this leaves INSERT - I'm guessing here you only want to insert an empty address for new users?:
ALTER TRIGGER [dbo].[autoupdate]
ON [dbo].[USERS]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO ADDRESSES(USID)
SELECT USID FROM INSERTED i
WHERE NOT EXISTS (SELECT 1 FROM ADDRESSES a WHERE a.USID = i.USID)
AND i.USID IS NOT NULL;
END
In order for your trigger to do anything the way you've designed it, you need to have records already in the Addresses table. Once a record exists, it's USID will be updated when a record is updated or inserted in the Users table.
Normally I used Windows authentication with MSSQL server. There were schemas in databases which correspond to specific Windows logins. These schemas I used for stored procedures, but underlying tables were dbo with default permissions.
Now I try to use SQL Server internal authentication and the server writes:
The SELECT permission was denied on the object 'XXXX', database 'nnnnnn', schema 'dbo'.
where XXXX is a table name.
Here is a script to create database:
CREATE LOGIN the_user WITH PASSWORD = 'kjzgfkzf'
GO
USE [master]
GO
CREATE DATABASE [my_database]
GO
USE [my_database]
GO
CREATE USER [the_user] FOR LOGIN [the_user] WITH DEFAULT_SCHEMA=[lic]
GO
CREATE SCHEMA [lic] AUTHORIZATION [the_user]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE App(
AppId int IDENTITY(1,1) NOT NULL,
AppName nvarchar(255) NOT NULL,
CONSTRAINT [PK_App] PRIMARY KEY CLUSTERED
(
[AppId] 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 IDENTITY_INSERT App ON
INSERT App (AppId, AppName) VALUES (1, N'Adobe Photoshop 1.0')
INSERT App (AppId, AppName) VALUES (2, N'Microsoft Windows 3.11')
INSERT App (AppId, AppName) VALUES (3, N'ABBYY Fine Reader 8.0')
INSERT App (AppId, AppName) VALUES (4, N'Microsoft Office 2007')
INSERT App (AppId, AppName) VALUES (5, N'ABBYY Lingvo 12')
SET IDENTITY_INSERT App OFF
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [User](
UserId int IDENTITY(1,1) NOT NULL,
[Login] varchar(50) NOT NULL,
[Password] varchar(50) NOT NULL,
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
(
[UserId] 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_PADDING OFF
GO
SET IDENTITY_INSERT [User] ON
INSERT [User] (UserId, [Login], [Password]) VALUES (1, N'asdfff', N'12345')
INSERT [User] (UserId, [Login], [Password]) VALUES (2, N'luke', N'sdjkh')
INSERT [User] (UserId, [Login], [Password]) VALUES (3, N'arny12', N'jfylufyul')
SET IDENTITY_INSERT [User] OFF
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE lic.User_Find
#Login VARCHAR(50),
#Password VARCHAR(50)
AS
SELECT
UserId
FROM [User]
WHERE
[Login] = #Login
AND [Password] = #Password
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [License](
UserId int NOT NULL,
AppId int NOT NULL,
Amount int NOT NULL,
CONSTRAINT [PK_License] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[AppId] 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
INSERT License (UserId, AppId, Amount) VALUES (1, 1, 5)
INSERT License (UserId, AppId, Amount) VALUES (1, 2, 2)
INSERT License (UserId, AppId, Amount) VALUES (2, 2, 1)
INSERT License (UserId, AppId, Amount) VALUES (2, 3, 1)
INSERT License (UserId, AppId, Amount) VALUES (2, 5, 3)
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE lic.License_List
#UserId INT
AS
SELECT
a.AppId,
a.AppName,
l.Amount
FROM
license l
INNER JOIN app a ON a.AppId = l.AppId
WHERE
l.UserId = #UserId
GO
ALTER TABLE [dbo].[License] ADD CONSTRAINT [DF_License_Amount] DEFAULT ((0)) FOR [Amount]
GO
ALTER TABLE [dbo].[License] WITH CHECK ADD CONSTRAINT [FK_License_App] FOREIGN KEY([AppId])
REFERENCES [dbo].[App] ([AppId])
GO
ALTER TABLE [dbo].[License] CHECK CONSTRAINT [FK_License_App]
GO
ALTER TABLE [dbo].[License] WITH CHECK ADD CONSTRAINT [FK_License_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([UserId])
GO
ALTER TABLE [dbo].[License] CHECK CONSTRAINT [FK_License_User]
GO
Could you suggest this script change which will make the server using underlying tables without setting explicit permissions on each of them?