Accessing table returning by table-valued function from SP - sql

I have table valued function
ALTER FUNCTION [dbo].[fn_Functiont]()
RETURNS TABLE
AS
RETURN
(
SELECT d.*, b.Name AS Name, ps.Name AS PaymentSystemName, c.UserName AS UserName, c.FirstName AS ClientFirstName, c.LastName AS LastName, c.Number AS DocumentNumber, c.Id
FROM Document AS d
JOIN System AS ps ON d.SystemId = ps.Id
JOIN Client AS c ON c.Id = d.ClientId
LEFT JOIN Shop AS b ON b.Id = d.ShopId
WHERE d.OperationTypeId IN (2, 4, 5) AND c.Type = 1
)
And SP. In that SP i have declared temporary table like this
DECLARE #tempTable AS TABLE
(
.. columns here ...
)
after declaring i just inserting info
INSERT INTO #tempTable
SELECT * FROM [dbo].[fn_Functiont]()
Select #column1,colum2...,from #tempTable
The problem is that i have to declare a lot of columns in #temptable and code looks like ugly.So is there a better way to reading rows in SP from table valued function?

Instead of table Variable #tempTable Use Temp Table and Try This
SELECT * INTO #tempTable FROM [dbo].[fn_Functiont]()

Related

Getting data from two tables not working SQL

I am trying to get data from two tables based on a condition. Both tables has the same condition just the content change. B contains client data and A contain product data
I am using this this code for stored procedure
ALTER PROCEDURE [dbo].[printfatura]
#idfatura int
AS
SELECT DISTINCT *
FROM tbl_faturimi b, tblfaturimi_details a
WHERE b.ID_FATURES = #idfatura
AND a.NR_FATURES = #idfatura
If I choose the ID =2 then then I should take the result of 3 rows as much as the table has , but instead I am getting 6 row. Data are repeated or duplicate. In tables there is not duplicate or repeated data, but during the select query process I get repeated data.
What should I change in this code to make it work?
Thanks to everyone
The photos of data :https://www.sendspace.com/file/fk6c1u
Try this
ALTER PROCEDURE [dbo].[printfatura]
#idfatura int
AS
SELECT DISTINCT *
FROM tbl_faturimi inner join tblfaturimi_details a
ON b.ID_FATURES=a.NR_FATURES
WHERE b.ID_FATURES = #idfatura
AND a.NR_FATURES = #idfatura
OR
ALTER PROCEDURE [dbo].[printfatura]
#idfatura int
AS
SELECT DISTINCT *
FROM tbl_faturimi b, tblfaturimi_details a
WHERE b.ID_FATURES = #idfatura
AND a.NR_FATURES = #idfatura
AND b.ID_FATURES=a.NR_FATURES
As per the syntax When we try to join two table we have to write a ON clause which contains the matching columns of both tables.
Use inner join and group by clause.
SELECT A.*, B.*
FROM tbl_faturimi A
INNER JOIN tblfaturimi_details B
ON A.FEATURES = B.FEATURES
GROUP BY A.*, B.*;
Hope this helps. :)
ALTER PROCEDURE [dbo].[printfatura]
#idfatura int
AS
BEGIN
SELECT A.*, B.*
FROM tbl_faturimi A
INNER JOIN tblfaturimi_details B
ON A.fk_ID = B.pk_ID
GROUP BY A.SomeColumn
WHERE A.fk_ID = #idfatura
END;

changing temp tables to declaring them

Just a question regards to temp tables and declaring table. If I change the temp tables 'ChangedData' and 'PackageDatatoProcess' to their own variables '#ChangedData' and '#PackageDatatoProcess', can I ask how I am suppose to change the select into statement as I have not quite done this before. Virtually I told that we can declare tables rather than using the select into but just need a bit of help with this:
select distinct * into #PackageDataToProcess from #ChangedData pp
outer apply (
select pk.Reference, pjl.PackageToJournalLinkId, j.CreatedDate, pccl.PackageCostChangeLogId from Jet2Holidays.dbo.Package pk
inner join Jet2Holidays.dbo.PackageToJournalLink pjl on pk.PackageId = pjl.PackageId
inner join Jet2Holidays.dbo.Journal j on pjl.JournalId = j.JournalId
and j.PrincipalName= iif(#AllowNonSupportChanges = 0, 'HolidaysSupport', j.PrincipalName)
inner join Jet2Holidays.dbo.BusinessProcess bp on pjl.BusinessProcessId = bp.BusinessProcessId
and bp.[Description] = iif(#AllowNonSupportChanges = 0, 'CallCentreAction', bp.[Description])
left outer join Jet2Holidays.dbo.PackageCostChangeLog pccl on pccl.PackageToJournalLinkId = pjl.PackageToJournalLinkId
where pk.Reference = pp.PackageReference
and pp.JournalID = pjl.JournalId
) as packageData
First, you declare your variable tables like so:
DECLARE #PackageDataToProcess TABLE
(
Reference UNIQUEIDENTIFIER
, PackageToJournalLinkId INT
, CreatedDate DATETIME
, PackageCostChangeLogId INT
, {other columns here}
)
DECLARE #ChangedData TABLE
(
Reference UNIQUEIDENTIFIER
, PackageToJournalLinkId INT
, CreatedDate DATETIME
, PackageCostChangeLogId INT
, {other columns here}
)
At this point you can populate your #ChangedData table like so:
INSERT #ChangedData ( Reference, PackageToJournalLinkId, CreatedDate, PackageCostChangeLogId, {other columns})
SELECT Reference, PackageToJournalLinkId, CreatedDate, PackageCostChangeLogId, {other columns}
FROM ChangedDataSource -- Table, Procedure, Function
And then you can run your code by substituting #PackageDataToProcess for #PackageDataToProcess. Here it is again with a slight re-write (from the original):
INSERT #PackageDataToProcess
select distinct pp.* from #ChangedData pp
outer apply (
select pk.Reference, pjl.PackageToJournalLinkId, j.CreatedDate, pccl.PackageCostChangeLogId from Jet2Holidays.dbo.Package pk
inner join Jet2Holidays.dbo.PackageToJournalLink pjl on pk.PackageId = pjl.PackageId
inner join Jet2Holidays.dbo.Journal j on pjl.JournalId = j.JournalId
and j.PrincipalName= iif(#AllowNonSupportChanges = 0, 'HolidaysSupport', j.PrincipalName)
inner join Jet2Holidays.dbo.BusinessProcess bp on pjl.BusinessProcessId = bp.BusinessProcessId
and bp.[Description] = iif(#AllowNonSupportChanges = 0, 'CallCentreAction', bp.[Description])
left outer join Jet2Holidays.dbo.PackageCostChangeLog pccl on pccl.PackageToJournalLinkId = pjl.PackageToJournalLinkId
where pk.Reference = pp.PackageReference
and pp.JournalID = pjl.JournalId
) as packageData
Your declared tabled will go out of scope in a similar manner to the way your non-global temporary table do.

How to Retrieve Column Headers of a Select Query?

How it is possible to retrieve column headers of a select query as a single column in SQL Server ? (it is preferred to retrieve data type of columns )
Query example:
select a.PartId, a.PartName, b.GroupName
from Parts as a
inner join Groups as b on a.GroupRef = b.GroupId
Expected result:
Columns
--------
PartId
PartName
GroupName
Starting from SQL Server 2012+ you can use sys.dm_exec_describe_first_result_set to get all metadata about result set:
DBFiddle Demo
DECLARE #tsql NVARCHAR(MAX) =
N'select a.PartId , a.PartName , b.GroupName
from Parts as a inner join Groups as b
on a.GroupRef = b.GroupId';
SELECT name AS [Columns]
FROM sys.dm_exec_describe_first_result_set(#tsql, NULL, 1)
One way is to create a temporary table with the schema of resultset and then query tempdb's schema table to get the column names and details. You can get all needed details.
select a.PartId , a.PartName , b.GroupName into #yourtable
from Parts as a inner join Groups as b
on a.GroupRef = b.GroupId
where 1=2
SELECT c.name as columnname,t.name as datatype
FROM tempdb.sys.columns c
inner join tempdb.sys.systypes as t on t.xtype = c.system_type_id
WHERE [object_id] = OBJECT_ID(N'tempdb..#yourtable');
SELECT 'PartId', 'PartName', 'GroupName'
UNION ALL
select a.PartId , a.PartName , b.GroupName
from Parts as a inner join Groups as b
on a.GroupRef = b.GroupId

How to insert record into table result of other Select Query?

My requirement is to insert record from selected query result in to new table.
My query is
SELECT
a.Section_name, b.sectionname, a.SubQno, b.Qno, a.ans, b.Answ,
a.Exame_id, b.Exame_id AS Expr1, b.User_id, b.Start_time, b.End_time
FROM Question AS a
INNER JOIN Solve_Student_question AS b ON a.SubQno = b.Qno AND a.Section_name = b.sectionname
WHERE (b.User_id = 'gopal ram51765078')
Now this query result stored in to Temp table. How can I do this?
You can use the Insert Into ... Select idiom like so:
INSERT INTO TempTable
(...) --Columns
SELECT
a.Section_name, b.sectionname, a.SubQno, b.Qno, a.ans, b.Answ, a.Exame_id, b.Exame_id AS Expr1, b.User_id, b.Start_time, b.End_time
FROM Question AS a INNER JOIN
Solve_Student_question AS b ON a.SubQno = b.Qno AND a.Section_name = b.sectionname
WHERE (b.User_id = 'gopal ram51765078')
You can use Cursor also for this case
declare
cursor C is
select a.Section_name, b.sectionname, a.SubQno, b.Qno, a.ans,
b.Answ, a.Exame_id, b.Exame_id AS Expr1, b.User_id, b.Start_time, b.End_time
FROM Question AS a INNER JOIN
Solve_Student_question AS b ON a.SubQno = b.Qno AND a.Section_name = b.sectionname
WHERE (b.User_id = 'gopal ram51765078');
begin
for i in C
insert into tablename(Column1,Column2,Column3)
values(i.column1,i.Column2,i.Column3);
end loop;
Exit when last.record = 'TRUE';
end;
`
`
insert into [temptablename] (comma-separated list of column names)
(your Select Query Here)

Only one expression can be specified in the select list when the subquery is not introduced with EXISTS

this is my query
Create FUNCTION [dbo].[CountUses](#couponid INT)
RETURNS INT
AS
BEGIN
RETURN
(
SELECT c.Id,
c.Name,
c.CreateDate,
Count(cu.id) NofUses
FROM Coupon as c
JOIN CouponUse as cu
ON c.id = cu.couponid
GROUP BY c.Id,
c.Name,
c.CreateDate
)
END
its giving the error Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. where is the problem ?
Aside from the main answer, I'd also appreciate any comments you may have about optimizing my query...
If you want your function to return more than one value, then you need to look at Table-Valued Functions.
These types of functions return a table and not just one value. Your current function is set up as a scalar function so it can only return one value.
If you want a scalar value - let's say just the count then your function will be similar to this:
Create FUNCTION [dbo].[CountUses](#couponid INT)
RETURNS INT
AS
BEGIN
RETURN
(
SELECT Count(cu.id) NofUses --- this can only return one column
FROM Coupon as c
JOIN CouponUse as cu
ON c.id = cu.couponid
WHERE cu.couponid = #couponid
)
END
If you intention is to return a table of data, then your function will be similar to this:
Create FUNCTION [dbo].[CountUses](#couponid INT)
RETURNS #new_table table
(
id int,
name varchar(50),
CreateDate datetime,
NofUsers int
)
AS
BEGIN
INSERT INTO #new_table
SELECT c.Id,
c.Name,
c.CreateDate,
Count(cu.id) NofUses
FROM Coupon as c
JOIN CouponUse as cu
ON c.id = cu.couponid
WHERE cu.couponid = #couponid
GROUP BY c.Id, c.Name, c.CreateDate
RETURN
END
This will fix the issue:
Create FUNCTION [dbo].[CountUses](#couponid INT)
RETURNS TABLE
AS
RETURN
(
SELECT c.Id,
c.Name,
c.CreateDate,
Count(cu.id) NofUses
FROM Coupon as c
JOIN CouponUse as cu
ON c.id = cu.couponid
GROUP BY c.Id,
c.Name,
c.CreateDate
)