How nest Select statement - sql-server

I have select like this:
SELECT UserName FROM Users WHERE userId= #UserId;
I want to get this value and use as register into insert
I try:
INSERT INTO Product.ProductDetail VALUES (
SELECT UserName FROM Users WHERE userId= #UserId;
);
but I get invalid column, how is the correct way to do this?

Your syntax is incorrect. The proper way does not have VALUES keyword in INSERT INTO...SELECT
INSERT INTO Product.ProductDetail (ColumnName) -- Must specify target column if you have multiple columns in the table
SELECT UserName
FROM Users
WHERE userId= #UserId

INSERT INTO Product.ProductDetail (UserName)
SELECT UserName FROM Users WHERE userId= #UserId
You'll need to specific insert column names if you have auto increment key in your table to be inserted.

Related

Sql Select query on select query result

I am trying to (select)query inside the previous (select)query from same table.
I've tried this below;
CREATE PROCEDURE dbo.strprcReturnEmpDetails(#EmpID VARCHAR(25))
AS
SELECT [Name],
Role,
Email,
Department,
ReportingAuthority,
DomainID,
ReportsTo,
(
SELECT DISTINCT
EmpID
FROM Login
WHERE [Name] = ReportsTo
) AS approverEmpid
FROM Login
WHERE EmpID = 288;
SET NOCOUNT ON;
RETURN;
I believe you just miss the aliases in the subquery to make it work. Your subquery returns more than one value, you need to make it a dependent subquery as follows:
SELECT [Name], Role, Email, Department, ReportingAuthority,DomainID,ReportsTo,
(
select distinct EmpID
from Login l2
where l2.Name = l1.ReportsTo
) as approverEmpid
FROM Login l1
WHERE EmpID=288
This should work if Name in Login table is unique.

How to compare varbinary data type in where clause

I have a linked server that is created to pull user details from a specific Organisation Unit with a scheduled sql job agent.
The table is created to hold user details has a column for ObjectGUID number and the type is defined as varbinary(50) (I am not sure why..).
The process checks if there is a new user by comparing the ObjectGUID number the saved Users table and if there is a new number then insert the new user in the table.
However I have noticed that the comparisons actually not really working properly.
SELECT
tbl.objectGUID AS UserGUID
FROM [dbo].[ActiveDirectoryUsers] tbl
WHERE tbl.objectGUID NOT IN (SELECT UserGUID FROM dbo.Users)
When I create a new user the new user is appearing in the ActiveDirectoryUsers view.
but when the where clause added to compare results with Users table then result is always empty. It looks like I need to cast or convert the varbinary to varchar then do the comparisons. I tried to cast the varbinary into varchar and uniqueidentifier but still it does not work.
Any idea how would I do the comparisons?
Update
CREATE VIEW [dbo].[ActiveDirectoryUsers] AS
SELECT "SAMAccountName" AS sAMAccountName, "mail" AS Email,
"objectGUID" AS objectGUID
FROM OpenQuery(ADSI, 'SELECT SAMAccountName, mail, objectGUID
FROM ''ldapconnectionstring.com''')
An example of objectGUID in the Users table
0x1DBCC071C69C8242B4895D42750969B1
You should not cast varbinary to smth particular to be able to use it in WHERE clause.
Your problem is that you use NOT IN where NULL values are present.
Try to execute my code first as it is (it will return 1 row) and then uncomment NULL value insert and execute it again.
This time you'll get 0 rows:
declare #t1 table (guid varbinary(50))
insert into #t1
values(0x1DBCC071C69C8242B4895D42750969B1)--, (null);
declare #t2 table (guid varbinary(50))
insert into #t2
values(0x1DBCC071C69C8242B4895D42750969B1), (0x1DBCC071C69C8242B4895D42750969B2);
select *
from #t2 t2
where t2.guid not in (select guid from #t1);
To fix your problem, try to use NOT EXISTS instead of NOT IN like this:
select *
from #t2 t2
where not exists (select *
from #t1 t1
where t1.guid = t2.guid);
In your case the code should be like this:
SELECT tbl.objectGUID AS UserGUID
FROM [dbo].[ActiveDirectoryUsers] tbl
WHERE not exists (SELECT *
FROM dbo.Users u
where u.UserGUID = tbl.objectGUID );

SQL trigger with IDENTITY_INSERT

I have two tables: Table1 is all the companies, Table2 is companies whose name start with A.
Table1 company (companyId int, companyName varchar(50), companySize int)
Table2 companyStartWithA (companyId int, companyName varchar(50), companySize int)
What I want to do is to create a trigger so that when I insert/update/delete something in Table1, it will automatically do the same in Table2
My code:
CREATE TRIGGER A_TRG_InsertSyncEmp
ON company
AFTER INSERT
AS
BEGIN
INSERT INTO companyStartWithA
SELECT *
FROM INSERTED
WHERE inserted.companyName LIKE 'A%'
END
And I get an error:
An explicit value for the identity column in table 'companyStartWithA' can only be specified when a column list is used and IDENTITY_INSERT is ON.
What can I do?
Thanks
The problem is the fact that you're not explicitly specifying the column in the INSERT statement, and using a SELECT * to fill the data. Both are big no-no's - you should always explicitly specify the column that you want to insert into, and you should always explicitly specify the columns that you want to select. Doing so will fix this problem:
CREATE TRIGGER A_TRG_InsertSyncEmp
ON company
AFTER INSERT
AS
BEGIN
INSERT INTO companyStartWithA (companyName, companySize)
SELECT companyName, companySize
FROM INSERTED
WHERE inserted.companyName LIKE 'A%'
END
But as Sean Lange absolutely correctly commented - this should really be just a view rather than a separate table.....
CREATE VIEW dbo.CompanyStartsWithA
AS
SELECT companyId, companyName, companySize
FROM dbo.Company
WHERE Name LIKE 'A%'
and then you don't need any messy triggers or anything - just insert into dbo.Company and all companies with a name that starts with an A will be visible in this view....

MS SQL trigger remove all before

Need some help...
I have a column whereby the data is shown as -
USEREMAIL:-USERNAME
e.g.
John.smith#test.com:-JSmit
janet.smit#test.co.uk:-JanSmit
peter.parker#test.ca:-PPark
I need a trigger that will automatically remove everything apart from the username when a new entry is added.
So the above examples would just become
JSmit
JanSmit
PPark
Any suggestions would be greatly appreciated.
Here is the syntax to create the described trigger:
Test table:
CREATE TABLE xx(UserName varchar(100))
You will have to expand the trigger to contain all columns.
Trigger syntax:
CREATE TRIGGER xx_trggr
ON xx
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO xx (UserName)
SELECT stuff(UserName, 1, charindex(':-', UserName) + 1, '')
FROM inserted
END
GO
Inserting data:
INSERT xx(UserName)
values
('John.smith#test.com:-JSmit'),
('janet.smit#test.co.uk:-JanSmit'),
('peter.parker#test.ca:-PPark')
Testing input:
SELECT UserName FROM xx
Result:
UserName
JSmit
JanSmit
PPark
You could make an AFTER trigger instead, but that would require a unique key
Using this table instead:
CREATE TABLE xx(id int identity(1,1), UserName varchar(100))
And this trigger:
CREATE TRIGGER xx_trggr
ON xx
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
UPDATE xx
SET [UserName] = stuff(xx.UserName, 1, charindex(':-', xx.UserName) + 1, '')
FROM inserted JOIN xx On inserted.id = xx.id
END
Same result as the other trigger.
You need to create a AFTER INSERT trigger on your table and in your trigger body use something like below to strip down the email part
select right('John.smith#test.com:-JSmit',(LEN('John.smith#test.com:-JSmit') - CHARINDEX('-','John.smith#test.com:-JSmit')))
This will give you username from column
SET columnName= select SUBSTRING( columnName, CHARINDEX('-',columnName)+1 , LEN(columnName))
Use it in trigger
EDIT 1: (If you are worried your email can contain -)
SET columnName= select SUBSTRING( columnName, CHARINDEX(':-',columnName)+2 , LEN(columnName))

SQL Server query - how to insert selected values into another table

Here's what I am trying to do.
This is the select statement
select Id
from tblUsersPokemons
where UserId = 1 and PokemonPlace = 'bag'
Now I want to insert those returned Ids into another table like this:
foreach all returned Ids
insert into tblNpcBattleUsersPokemons values (Id, 1)
How can I do that ?
Like this:
insert into tblNpcBattleUsersPokemons
select Id, 1 from tblUsersPokemons where UserId=1 and PokemonPlace='bag'
This can be done in a single sql call
insert into tblNpcBattleUsersPokemons (id, [whatever the name of the other column is])
select Id, 1 from tblUsersPokemons where UserId=1 and PokemonPlace='bag'
I've used the longhand here because it does not make any assumption about the ordering of columns in the destination table, which can change over time and invalidate your insert statement.
You can insert the set retrieved by a SELECT into another existing table using the INSERT...SELECT syntax.
For example:
INSERT INTO tblNpcBattleUsersPokemons (Id, Val) -- not sure what the second column name was
SELECT Id FROM tblUsersPokemons WHERE UserID = 1 and PokemonPlace='bag';

Resources