Get string by integer - sql

I have a column in db stores Entityid and other one stores Entityname , i need a stored procedure that get name when user insert id (by column name), i have one am working on, how can i improve it.plz explain..
ALTER procedure [dbo].[Emp_CompanyHirarchy]
#FK_CompanyId varchar(50),
#FK_EntityId varchar(50)
AS
SELECT * FROM dbo.RetrieveEntityParent
WHERE (EntityId =#FK_EntityId)
when i excute this, error keeps raise:Msg 216, Level 16, State 1, Procedure Emp_CompanyHirarchy, Line 5
Parameters were not supplied for the function 'dbo.RetrieveEntityParent'.
the function dbo.RetrieveEntityParent:
ALTER FUNCTION [dbo].[RetrieveEntityParent] (#FK_EntityId int)
RETURNS TABLE
AS RETURN
with p as
(SELECT EntityId, FK_ParentId , EntityName ,EntityArabicName
FROM OrgEntity
WHERE OrgEntity.EntityId=#FK_EntityId
UNION ALL
SELECT PA.EntityId, PA.FK_ParentId, PA.EntityName,PA.EntityArabicName
FROM OrgEntity as PA
inner join p
ON p.FK_ParentId = PA.EntityId)
select * from p

There is an example for your need in this link , but there is a simpler way using the parameter directly in this link .
DECLARE #FK_EntityId INT
SET #FK_EntityId = 1
SELECT EntityId, FK_ParentId , EntityName ,EntityArabicName
FROM OrgEntity
WHERE OrgEntity.EntityId = #FK_EntityId
UNION ALL
SELECT EntityId, FK_ParentId , EntityName ,EntityArabicName
FROM OrgEntity
WHERE FK_ParentId = #FK_EntityId

I can't find Employee referred by Employee.FK_EntityId in your RetrieveEntityParent.
Do you mean OrgEntity.FK_EntityId
after your Edit, to get Emp_CompanyHirarchy work you would have to transfer #FK_EntityId as parameter
ALTER procedure [dbo].[Emp_CompanyHirarchy]
#FK_CompanyId varchar(50),
#FK_EntityId varchar(50)
AS
SELECT * FROM dbo.RetrieveEntityParent(#FK_EntityId)
-- WHERE mybe some other condition
BTW: there is some parametertype missmatch with varchar and integer

Related

SQL Server XML queries

I'm trying to find a solution for this task: write a procedure that accepts XML document in the following format:
<Buyer N="John" S="Doe" CTY="Madrid" CTR="Spain">
<E>John.Doe#gmail.com</E>
<T>123456789</T>
</Buyer>
The procedure must verify if your database already contains the country, city or buyer (check buyer by email).
If any data is missing in your database, your procedure has to insert it into the table.
Call the functions that show the mentioned procedure functionalities.
This is how I started to separate all the important things:
CREATE PROCEDURE pXML
#var XML
AS
SELECT
X.U.value('#N', 'nvarchar(20)') AS pName,
X.U.value('#S', 'nvarchar(20)') AS pSurename,
X.U.value('#CTY', 'nvarchar(20)') AS pCity,
X.U.value('#CTR', 'nvarchar(20)') AS pCountry
FROM
#var.nodes('/Buyer') AS X(U)
SELECT X.U.value('.', 'nvarchar(50)' ) AS pEmail
FROM #var.nodes('/Buyer/E') as X(U)
What I don't know is how to put IF statement, or whatever condition is necessary INSIDE that procedure.
My pseudo code would be:
declare #temp nvarchar(30)
set #temp = pEmail
IF NOT EXISTS(select * from Buyers where Buyer.Email = pEmail)
INSERT INTO Buyer values (pName, pSurename, pCity, pCountry)
(more IF NOT EXISTS statements for city and for country)
Is anyone willing to give me a hand here?
Thanks in advance! Tell me if didn't clarify enough, I'll do my best to add any needed info.
Please try the following solution.
It is using MERGE statement to handle INSERT or UPDATE based on the email.
SQL
-- DDL and sample data population, start
DECLARE #Buyer TABLE (
ID INT IDENTITY PRIMARY KEY,
pEmail NVARCHAR(100),
pName nvarchar(20),
pSurename nvarchar(20),
pCity nvarchar(20),
pCountry nvarchar(20)
);
INSERT INTO #Buyer (pEmail, pName, pSurename, pCity, pCountry) VALUES
(N'John.Doe#gmail.com', N'John', N'Doe', N'Madrid', N'Spain');
-- DDL and sample data population, end
-- before
SELECT * FROM #Buyer;
DECLARE #var XML =
N'<Buyer N="Johnny" S="Doe" CTY="Barcelona" CTR="Spain">
<E>John.Doe#gmail.com</E>
<T>123456789</T>
</Buyer>';
MERGE INTO #Buyer as Trg
USING (
SELECT c.value('(E/text())[1]', 'nvarchar(100)') as pEmail
, c.value('#N', 'nvarchar(20)') as pName
, c.value('#S', 'nvarchar(20)') as pSurename
, c.value('#CTY', 'nvarchar(20)') as pCity
, c.value('#CTR', 'nvarchar(20)') as pCountry
FROM #var.nodes('/Buyer') AS t(c)
) as Src
ON Trg.pEmail = Src.pEmail
WHEN Matched /*AND Src.pName IS NOT NULL*/ THEN -- if needed to add additional conditions
UPDATE
SET Trg.pName = Src.pName
, Trg.pSurename = Src.pSurename
, Trg.pCity = Src.pCity
, Trg.pCountry = Src.pCountry
WHEN NOT MATCHED THEN
INSERT (pEmail, pName, pSurename, pCity, pCountry) VALUES
(Src.pEmail, Src.pName, Src.pSurename, Src.pCity, Src.pCountry)
OUTPUT
$action ,
inserted.*;
-- after
SELECT * FROM #Buyer;

SQL Update Based on Subquery

I am having trouble coming up with this SQL statement to go and update certain records that already exist. For the sake of brevity, I am using hard coded values.
What I want to do is the following:
When there is already a record within the PersonXNotifyUser table where the UserID and NotifyUserID match, I want to make sure that I update the IsDeleted column to a value of 0, and also update the ModifiedBy and ModifiedDate columns accordingly. Here is what I have so far, which doesn't execute, but am hoping someone can help me out:
UPDATE: Since one of the answers assumed there is need for a subquery, I have added the Table Type and the stored procedure definition which expects the Table Valued Parameter
CREATE TYPE dbo.GuidIDList
AS TABLE
(
ID [UNIQUEIDENTIFIER]
);
CREATE PROCEDURE [dbo].[PersonXNotifyUser_InsertUpdate]
(
,#UserID [UNIQUEIDENTIFIER]
,#NotifyUserIDs AS dbo.GuidIDList READONLY
,#EditingUserID [UNIQUEIDENTIFIER]
)
AS
SET NOCOUNT ON
UPDATE PersonXNotifyUser
SET IsDeleted = 0, ModifiedBy = #EditingUserID, ModifyDate = GETUTCDATE()
FROM (
SELECT
test.NotifyUserID
FROM (
SELECT ID FROM #NotifyUserIDs
)
AS test (NotifyUserID)
WHERE EXISTS
(SELECT PersonXNotifyUserID
FROM PersonXNotifyUser pnu
WHERE pnu.UserID = #UserID AND pnu.NotifyUserID = test.NotifyUserID
)
)
Based on the inputs given in the question, it does not seems like you need a join or subquery for achieving this. Use a Simple Update
DECLARE #UserID UNIQUEIDENTIFIER = '45D9F7E4-E111-4E62-8B1A-118F7C7FB6A1'
DECLARE #EditingUserID UNIQUEIDENTIFIER = 'CDFDBD9A-87FB-4F68-B695-F4A39424C207'
UPDATE PersonXNotifyUser
SET
IsDeleted = 0,
ModifiedBy = #EditingUserID,
ModifyDate = GETUTCDATE()
WHERE UserID = #UserID
AND EXISTS
(
SELECT
1
FROM #NotifyUserIDs
WHERE ID = PersonXNotifyUser.NotifyUserID
)

Table as parameter incorrect type

I created function and new type to hold my table but now I get error
Operand type clash: nchar is incompatible with TableArgId
I'm using the Northwind database.
My code below.
USE Northwind
CREATE TYPE TableArgId
AS TABLE
( ID NVARCHAR(16));
GO
CREATE or ALTER FUNCTION MyFunc
(
#clientid TableArgId READONLY
)
RETURNS #tablica TABLE(
CustomerID NVARCHAR(16),
Category_ID INT,
Category_Name NVARCHAR(128)
)
AS
BEGIN
INSERt INTO #tablica
SELECT
CustomerID,
B.CategoryID,
C.CategoryName
FROM
#clientid AS TabID LEFT JOIN
Invoices AS A ON TabID.ID = CustomerID
left join Products AS B ON A.ProductID=B.ProductID
left join Categories AS C ON B.CategoryID=C.CategoryID;
RETURN
END
GO
SELECT * FROM MyFunc((SELECT CustomerID FROM Invoices WHERE CustomerID = 'QUEEN'));
Can I set the type returned by the SELECT?
Can I set the type returned by the SELECT?
No - you have to assign it to a variable first e.g.
DECLARE #Param TableArgId;
INSERT INTO #Param (ID)
SELECT CustomerID
FROM Invoices
WHERE CustomerID = 'QUEEN';
SELECT *
FROM dbo.MyFunc(#Param);

Insert where not exists Violation of PRIMARY KEY

I'm having troubles with an Insert where not exists and I'm not sure if a MERGE statement would be more efficient or what's wrong with my statement.
I have en existing View and need to insert the new records of this View into a Table.
The Table looks like:
CREATE TABLE [dbo].[ser_number_all]
(Serialnumber nvarchar(100) PRIMARY KEY,
TypeName nvarchar(max),
Date datetime,
Parent_Serialnumber nvarchar(100),
JobNumber nvarchar(30),
ProductNode hierarchyid,
);
The Insert statement looks like this:
insert into [dbo].[ser_number_all]
( Serialnumber
, TypeName
, Date
, Parent_Serialnumber
, JobNumber
, ProductNode)
select Serialnumber
, TypeName
, Date
, Parent_Serialnumber
, JobNumber
, ProductNode
from dbo.Hierachical_View_with_Jobnumbers as ser_number_all
where not exists (select 1
from Hierachical_View_with_Jobnumbers as hv
where hv. Serialnumber = ser_number_all.Serialnumber
and hv. TypeName = ser_number_all.TypeName
and hv. Date = ser_number_all.Date
and hv. Parent_Serialnumber = ser_number_all.Parent_Serialnumber
and hv. JobNumber = ser_number_all.JobNumber
and hv. ProductNode = ser_number_all.ProductNode);
As long the View has not any new records, it looks ok and I'm not getting any error, the output is 0 records as it should be.
When I add a new record to the origin table and the view has 1 record more, I'm always getting this error:
Msg 2627, Level 14, State 1, Line 4
Violation of PRIMARY KEY constraint 'PK__ser_numb__F2753A12C4ABA976'. Cannot insert duplicate key in object 'dbo.ser_number_all'. The duplicate key value is (.x3666AB05).
The statement has been terminated.
I don't get it why it will insert a duplicate value in the primary key column because in my WHERE clause I can't see any mistake.
I have also tried with IS NULL instead = ser_number_all.TypeName and for all other columns where it could have a NULL value, but still the same.
Again, I'm coming from Oracle and it looks like I have to learn many diversities with MS SQL compared to Oracle.
Appreciate any suggestion :-)
Thx
EDIT:
Here the code of the View:
CREATE VIEW [dbo].[Hierachical_View_with_Jobnumbers]
AS
WITH ProductList
AS
(
SELECT p.Serialnumber,
p.Type_Id,
p.Parent_Serialnumber,
p.ActiveJob_Jobnumber as JobNumber,
N'/' + CONVERT(NVARCHAR(4000), ROW_NUMBER() OVER (ORDER BY p.Serialnumber)) + N'/' AS ProductNode_AsChar
FROM Products AS p
WHERE p.Parent_Serialnumber IS NULL
UNION ALL
SELECT p.Serialnumber,
p.Type_Id,
p.Parent_Serialnumber,
JobNumber,
pl.ProductNode_AsChar + CONVERT(NVARCHAR(4000), ROW_NUMBER() OVER (ORDER BY p.Serialnumber)) + N'/'
FROM Products AS p
INNER JOIN ProductList AS pl ON p.Parent_Serialnumber = pl.Serialnumber
)
SELECT Serialnumber,
pt.Name as TypeName,
Parent_Serialnumber,
JobNumber,
CONVERT(HIERARCHYID, ProductNode_AsChar) AS ProductNode
FROM ProductList as pl
INNER JOIN ProductTypes as pt on pl.Type_Id = pt.Id;
#TheGameiswar
Sorry, now I got it what you meant ;-) Stupid me...
Here the solution which works now with correctly correlating:
insert into [dbo].[ser_number_all]
( Serialnumber
, TypeName
, Date
, Parent_Serialnumber
, JobNumber
, ProductNode)
select Serialnumber
, TypeName
, Date
, Parent_Serialnumber
, JobNumber
, ProductNode
from dbo.Hierachical_View_with_Jobnumbers as hv
where not exists (select 1
from ser_number_all as sna
where hv. Serialnumber = sna.Serialnumber);
Thank you all for your time and guiding me to the right direction :-)

SQL - Table Type / passing a table as a paramater

I have a stored procedure that takes in a table as a parameter.
For example: I have a type PartsImport:
CREATE TYPE PartsImport AS TABLE
(
Number_Key varchar(10),
LogDate smalldatetime,
FullName varchar(125),
Descrip varchar(250)
);
Then the stored procedure takes in this param:
#PTable PartsImport ReadOnly
The stored procedure does an insert into a table via a simple select * from #PTable, but now I need to join this table variable with other tables when creating the select statement, but I always get an error message
Must declare the scalar variable "#PPTable"
How do you select an individual column from this #PTable? I tried #PTable.LogDate, but it doesn't like the syntax. Is it possible to use the variable table in a join and select the columns or does it only work with select * ?
You can try using an Alias to refer to your table, instead of the variable name. For example:
SELECT P.LogDate FROM #PTable AS P
try with below example, when you fetch column only from table variable then works fine but when you use in join you must use alias name with table variable name.
CREATE TYPE PartsImport AS TABLE
(
Number_Key varchar(10),
LogDate smalldatetime,
FullName varchar(125),
Descrip varchar(250)
);
create table PartsImportother (col1 varchar(10), col2 varchar(3))
insert into PartsImportother values('1','ads')
Declare #table PartsImport
insert into #table(Number_Key,LogDate,FullName,Descrip) values('1','01-01-2015','aaa','adsfadfa')
-- select [specific column] from [only table variable]
select Number_Key from #table
-- select [specific column] from [table variable with join]
select T.Number_Key from #table as T inner join PartsImportother on T.Number_Key = PartsImportother.col1