Four (4) Sub Queries - sql

Is there any possible way to do this kind of sub query:
DELETE (INSERT (SELECT (INSERT)))
I know how to: INSERT (SELECT):
INSERT INTO r (u_id,role)
VALUES ((SELECT u_id FROM USER WHERE email="mumair1992#gmail.com"),'Agent');
My problem is:
User is present in request table when he verifies his account, system must have to:
Create user in user table
Create user role in role table
Delete user from request table

The reason you can do INSERT INTO .... SELECT ... is that the SELECT is being used as the input into the INSERT query.
However, an INSERT query doesn't return anything in that way. You are much better off just writing 3 distinct queries like this:
--Create user in user table
INSERT INTO UserTable VALUES (...)
--Create user role in role table
INSERT INTO UserRoles VALUES (...)
--Delete user from request table
DELETE FROM Requests WHERE ...
You could even wrap that all in a transaction to ensure all or none of the queries run:
BEGIN TRAN
--Create user in user table
INSERT INTO UserTable VALUES (...)
--Create user role in role table
INSERT INTO UserRoles VALUES (...)
--Delete user from request table
DELETE FROM Requests WHERE ...
COMMIT
I suspect also that you are wanting to use the ID of the user that you've created. To do this, assuming your UserTable has an IDENTITY column, you can use the SCOPE_IDENTITY function:
BEGIN TRAN
--Create user in user table
INSERT INTO UserTable VALUES (...)
DECLARE #UserID INT
SET #UserID = SCOPE_IDENTITY()
--Create user role in role table
INSERT INTO UserRoles (UserID, RoleID) VALUES (#UserID, ...)
--Delete user from request table
DELETE FROM Requests WHERE ...
COMMIT

Related

Track logins sql

I have a job that runs on my server to track the last login on my sql server so I can audit inactive users.
First I enabled track successful logins on the server
I created a table called TRACK_LOGIN and run this daily:
INSERT INTO dbadb.dbo.TRACK_LOGIN (logontime, logon, loginname) EXEC XP_READERRORLOG 0, 1, [LOGIN SUCCEEDED FOR USER]
Now that that information is in the TRACK_LOGIN table I query DISTINCT out of that table and put it in another table with this query:
SELECT DISTINCT SUBSTRING(LOGINNAME,PATINDEX('%''%',LOGINNAME)+1,PATINDEX('%.%',LOGINNAME)-PATINDEX('%''%',LOGINNAME))FROM TRACK_LOGIN
I would also like to query the column logontime along with the distinct login so I have a list daily of who logs in and what time they login?
Please help modify the select statement above to include distinct logins along with their last logontime.
This is intended on allowing me to look back at my users last login and eliminate those on the server that are not used.
I understand that you have already put some real effort into make this work, but I would still suggest to go with a different approach that yields a much cleaner result:
Logon triggers
This will allow you to insert the right type of data into your table and will not force you to parse back log entries.
This example here shows a different use case, but I think you will have no issue to port it to your own problem.
CREATE TRIGGER MyLogonTrigger ON ALL SERVER FOR LOGON
AS
BEGIN
IF SUSER_SNAME() <> 'sa'
INSERT INTO Test.dbo.LogonAudit (UserName, LogonDate, spid)
VALUES (SUSER_SNAME(), GETDATE(), ##SPID);
END;
GO
ENABLE TRIGGER MyLogonTrigger ON ALL SERVER;
Ok to track logins I did this, I abounded the first method and implemented this:
First I created a table called logonaudit:
CREATE TABLE LogonAudit
(
AuditID INT NOT NULL CONSTRAINT PK_LogonAudit_AuditID
PRIMARY KEY CLUSTERED IDENTITY(1,1)
, UserName NVARCHAR(255)
, LogonDate DATETIME
, spid INT NOT NULL
);
I then had to grant insert on that table:
GRANT INSERT ON dbadb.dbo.LogonAudit TO public;
I created another table called auditloginresults:
create table auditLoginResults
(
AuditID INT,
Username NVARCHAR(255),
LogonDate DATETIME,
SPID INT
);
I then created a trigger to log all logins and times to the first table LogonAudit. I had to create a logon called login_audit and allow it to insert into my tables. I then had to use the origional_login() to log the users login, if you dont do this it will block all logins that are not sa
CREATE TRIGGER MyLogonTrigger
ON ALL SERVER WITH EXECUTE AS 'login_audit'
FOR LOGON
AS
BEGIN
INSERT INTO DBADb.dbo.LogonAudit (UserName, LogonDate, spid)
VALUES (ORIGINAL_LOGIN(), GETDATE(), ##SPID);
END;
Now I created a job (you will need to create a job to run at a specific time with this code, This is not the code for the job just the code you would run in your job) to query the first table LogonAudit and put the results into the auditloginResults table, after that step I cleaned out the first table LogonAudit by running another step to delete data in the first table. Im not going to post the job to keep the threat clean but here is what is run in the job
The create job step 1--------------------------------------------------------
INSERT INTO DBADb.dbo.auditLoginResults
SELECT I.*
FROM DBADb.[dbo].[LogonAudit] AS I
INNER JOIN
(SELECT UserName, MAX([logondate]) AS MaxDate
FROM DBADb.[dbo].[LogonAudit]
GROUP BY UserName
) AS M ON I.logondate = M.MaxDate
AND I.UserName = M.UserName
`
-----NOW create job to purge the logonaudit table step 2
DELETE FROM dbadb.dbo.auditLoginResults;
-----now create a stored procedure to execute this will query the auditloginreaults and provide you the last login of everyone that has ever logged into the database
SELECT I.*
FROM DBADb.[dbo].[auditLoginResults] AS I
INNER JOIN
(SELECT UserName, MAX([logondate]) AS MaxDate
FROM DBADb.[dbo].[ auditLoginResults]
GROUP BY UserName
) AS M ON I.logondate = M.MaxDate
AND I.UserName = M.UserName

Insert multiple records into table for each user in another table in SQL Server

I want to create notification application in node js and I just created a database with these three tables in SQL Server:
tbluser
user_id
user_name
tbluser_notification
user_id
noti_id
read
tblnotification
noti_id
noti_title
noti_mesg
noti_create
noti_sender_id
My question is: whenever I insert a notification into tblnotification, I want to insert a record for each user into the tbluser_notification.
Create after insert trigger
CREATE TRIGGER [dbo].[trgtblnotificationInsert]
ON [dbo].[tblnotification]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO tbluser_notification (user_id, noti_id, notificationread)
SELECT tbluser.user_id, inserted.noti_id, 0
FROM tbluser
CROSS JOIN inserted
END
Please note: I have changed the column name 'read' to 'notificationread' as read is reserved word.

Trigger an Insert in another table when i insert a value on a table

I have one table that I log the status from some services.
I need to trigger an insert in another table when this table A receive one insert with the value FALSE.
Let me try to explain a little more:
I Have one table EMAIL into which I insert emails that I want to send. I Have another table LOG that logs one service. If the table LOG receives one insert on field STATUS with the value FALSE I want to trigger one insert in the table EMAIL.
Hi Try this...........
-------------Sample Table
create table [log] (Id int,[status] varchar(10))
create table Email ([Status] varchar(10),id int)
go
------------ Trigger Creation
create trigger tri_log on log
for insert
as
insert into email(id,[status])
select a.[id],a.[status]
from inserted a where a.[status] = 'false'
go
------------------Sample Check
select * from [log]
select * from [email]
-----------insert records for test
insert into [log] values (1,'True')
insert into [log] values (2,'False')
----------verify result
select * from [log]
select * from [email]

Trigger that creates a row in another table that is referenced by current table

I have 2 tables User and Account. I'd like to have a trigger that creates an account automatically when a user is created. Here is my code:
alter trigger Add_user on [user] for insert as
begin
insert into [account] (name) values ('Main')
declare #newAccountId int, #insertedId int
set #newAccountId = (select scope_identity())
set #insertedId = (select id from inserted)
update [user]
set accountId = #newAccountId
where id = #insertedId
end
I want to have AccountId in the User table be not null however when I try and create a new user it won't let me and I get an error complaining about the not null AccountId column :(
If you make [user].AccountId nullable, it should work.
Also consider following things:
does [account] table contain only column "name"? I.e. is it global
for all users? Then why create new account for each user? If it's
user-specific then add [account].[userId] column.
I would recommend to write stored procedure instead of trigger (first create
account record then user record), it's more explicit and safe. Be
careful with triggers, it's likely to be a surprise for other
developers that inserting user also creates account.

Updating associated table with the values imported from a comma-separated file

I have three tables:
Role
Permission
RolePermission (link table with just role id and permissionid)
I have a stored procedure that updates role
If I am passing permissionids associated with the role to the update stored procedure, I can use the function [dbo.Split][1] to split them good.
But after that how can I update rolepermission table?
Do I need to loop? And if so: how?
One possible way you could do this (lacking detailed information about your data - so guessing at times) would be:
BULK INSERT your CSV file into a temporary table, so you have both RoleID's and Permission ID's available (guessing that you have both in the CSV)
then use a transaction and several T-SQL statements to put the data into the proper places.
Step 1: BULK INSERT
You would need to use BULK INSERT to get your data into a temporary table:
CREATE TABLE #BulkImportTemp (RoleID INT, PermissionID INT)
BULK INSERT #BulkImportTemp
FROM 'c:\yourcsvfile.csv'
WITH
(FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n')
GO
SELECT * FROM #BulkImportTemp
Step 2: update the necessary tables
Now, once you have all that data in a temporary table, you can update the necessary tables:
START TRANSACTION
UPDATE dbo.Role
SET .......
FROM #BulkImportTemp tmp
WHERE ........
UPDATE dbo.Permission
SET .......
FROM #BulkImportTemp tmp
WHERE ........
INSERT INTO dbo.RolePermission(....)
SELECT ........
FROM #BulkImportTemp tmp
WHERE ........
COMMIT
UPDATE [ROLE] SET
ProductId=#ProductId,
[Name]=#Name
WHERE RoleId=#RoleId
DELETE FROM RolePermission WHERE RoleId=#RoleId
INSERT INTO RolePermission
SELECT #RoleId, P.Items
FROM dbo.Split(#PermisionIds, ',') P