How to put an SSRS built in variable into SQL variable - tsql

Building a report in SSRS 2008. I need to capture the built-in User!UserId variable so I can use it in my dataset query. It is part of my report security. I have tried a couple ways, but niether worked:
DECLARE #currentUser varchar(30) =User!UserID
and inline:
SELECT #retVal = COUNT(*)
FROM MySecurityTable
WHERE ExpirationTime > GETDATE() AND UserName =User!UserId

Create a Hidden report parameter #UserID and set its default value as =User!UserID.
Use the parameter #UserID in your dataset.
SELECT #retVal = COUNT(*)
FROM MySecurityTable
WHERE ExpirationTime > GETDATE() AND UserName = #UserID

Related

How to change a SQL KEYWORDS in a jrxml query?

I want to change ORDER BY statement in a jrxml
for example
SELECT * FROM table WHERE Id = 1 ORDER BY Name ASC
How to change ASC dynamic?
I tried below , but it's not work
SELECT * FROM table WHERE Id = $P{Id} ORDER BY Name $P{OrderType}
EXEC sp_executeSQL 'SELECT * FROM table WHERE Id = $P{Id} ORDER BY Name $P{OrderType}'
I have to change it in jrxml, so I cant use code like c# or java.

SQL Server, variable in IN Clause

I want to use a variable inside IN clause, similar to this:
Declare #tt NVARCHAR(MAX)
SET #tt = '02ea2b81-07f0-4660-bca1-81563f65bf65','07728975-cb1d-484c-8894-14f5b793cbef','1071ee4f-a214-443f-8694-0b3e9d2dc77e','120d2881-b04f-4707-a925-e4d941f03201','23af54a7-6666-4747-a74a-c2101cda59b0','260d2ce5-f4f0-4a0b-aa0b-3e1d2b5fcfeb','2710a913-13e7-4300-91f1-2646e2f8449e','2cebc482-4917-4aa3-973b-2481619a78e7','2d2269a4-9164-4dae-a732-90448d761509','2d29c707-1c5f-4e00-bd3c-bfd2ec2c6e29','3ead72a1-de91-47e9-8038-cc504a5274ec','40a03f53-7fd7-488d-922d-3435652219cb','43c93954-2e75-4d47-a53f-848eee609cf1','441e1a59-d397-4981-b770-01fb4594152e','4dacc9df-0536-46f6-af5d-78610ed998cd','4e4910ee-db9b-45ba-8872-2819dcefdc2c','4f9fd3ef-ba81-44bb-8c75-7cf6998e115e','60d9c73f-46c3-4ab1-9a4e-5440d18a0fd8','63e0cc57-1803-473f-847d-f3318f70c993','6510de61-9a1d-4f69-bec4-a744ea2bb847','799e2e55-2ba8-4772-8aff-331ed1817225','7be022db-4d37-4964-9005-3de7c6286027','85ba80c3-5c8b-4097-b5c9-c0d55ac6cf2f','8bc45b07-6a65-43c2-a41e-e791b085a053','8ca2d4a7-f4d6-4b56-aa41-42550e3a11b5','8fa7c3f6-e042-4b93-829f-79b8946a909e','ab34d18a-9482-4146-adb2-7e45e32f8cdd','ac43b44b-651c-4a98-a55f-82878cc8c656','ad9f222c-a98e-44eb-af9e-6f083941be9e','af7e8d24-9126-4d9b-a48a-75bf344c3529','b0e95518-0fef-46ba-81f4-0d1356ebc135','b1f1810f-3044-40b3-b218-5bb02d8922bd','b32ebf2b-f247-4032-8a37-285e4c3488a9','b93a8bb7-c62f-47b7-86ba-0421eb67ca14','c5342d7e-1667-47cb-bccf-91c5e8e9f18c','e2cf46f6-a522-4a96-8a84-f1ce3818c364','f01f4010-a192-43ca-a3bf-157379f4779d','f0f168ec-f043-41ef-90d3-3eac68b90334','f99af706-e1bb-42ba-bdf9-348a3b02c25e','fe691dee-b133-4d1c-90a3-8889cd3482d2';
Select * from table where assessmentId IN(#tt)
But this query is failing, saying Incorrect syntax near ','. The same query will work if I will not use variable in IN clause and directly pass the Id's
Select * from table where AssessmentId IN
('02ea2b81-07f0-4660-bca1-81563f65bf65','07728975-cb1d-484c-8894-14f5b793cbef','1071ee4f-a214-443f-8694-0b3e9d2dc77e','120d2881-b04f-4707-a925-e4d941f03201','23af54a7-6666-4747-a74a-c2101cda59b0','260d2ce5-f4f0-4a0b-aa0b-3e1d2b5fcfeb','2710a913-13e7-4300-91f1-2646e2f8449e','2cebc482-4917-4aa3-973b-2481619a78e7','2d2269a4-9164-4dae-a732-90448d761509','2d29c707-1c5f-4e00-bd3c-bfd2ec2c6e29','3ead72a1-de91-47e9-8038-cc504a5274ec','40a03f53-7fd7-488d-922d-3435652219cb','43c93954-2e75-4d47-a53f-848eee609cf1','441e1a59-d397-4981-b770-01fb4594152e','4dacc9df-0536-46f6-af5d-78610ed998cd','4e4910ee-db9b-45ba-8872-2819dcefdc2c','4f9fd3ef-ba81-44bb-8c75-7cf6998e115e','60d9c73f-46c3-4ab1-9a4e-5440d18a0fd8','63e0cc57-1803-473f-847d-f3318f70c993','6510de61-9a1d-4f69-bec4-a744ea2bb847','799e2e55-2ba8-4772-8aff-331ed1817225','7be022db-4d37-4964-9005-3de7c6286027','85ba80c3-5c8b-4097-b5c9-c0d55ac6cf2f','8bc45b07-6a65-43c2-a41e-e791b085a053','8ca2d4a7-f4d6-4b56-aa41-42550e3a11b5','8fa7c3f6-e042-4b93-829f-79b8946a909e','ab34d18a-9482-4146-adb2-7e45e32f8cdd','ac43b44b-651c-4a98-a55f-82878cc8c656','ad9f222c-a98e-44eb-af9e-6f083941be9e','af7e8d24-9126-4d9b-a48a-75bf344c3529','b0e95518-0fef-46ba-81f4-0d1356ebc135','b1f1810f-3044-40b3-b218-5bb02d8922bd','b32ebf2b-f247-4032-8a37-285e4c3488a9','b93a8bb7-c62f-47b7-86ba-0421eb67ca14','c5342d7e-1667-47cb-bccf-91c5e8e9f18c','e2cf46f6-a522-4a96-8a84-f1ce3818c364','f01f4010-a192-43ca-a3bf-157379f4779d','f0f168ec-f043-41ef-90d3-3eac68b90334','f99af706-e1bb-42ba-bdf9-348a3b02c25e','fe691dee-b133-4d1c-90a3-8889cd3482d2');
How can I use variable in IN clause using the first approach?
You will have to insert the values into a temp table.
Something like
DECLARE #TempTable TABLE(
assessmentId VARCHAR(50)
)
INSERT INTO #TempTable
VALUES
('02ea2b81-07f0-4660-bca1-81563f65bf65'),
('07728975-cb1d-484c-8894-14f5b793cbef'),
('1071ee4f-a214-443f-8694-0b3e9d2dc77e'),
('120d2881-b04f-4707-a925-e4d941f03201'),
('23af54a7-6666-4747-a74a-c2101cda59b0'),
('260d2ce5-f4f0-4a0b-aa0b-3e1d2b5fcfeb'),
('2710a913-13e7-4300-91f1-2646e2f8449e'),
('2cebc482-4917-4aa3-973b-2481619a78e7')
SELECT *
FROM table
where AssessmentId IN (SELECT assessmentId FROM #TempTable)
Since you want to specify multiple values, use a data type that supports multiple values (as opposed to a scalar variable). Here we're using a table variable:
Declare #tt table (value nvarchar(50) not null)
insert into #tt (value) values
('02ea2b81-07f0-4660-bca1-81563f65bf65'),('07728975-cb1d-484c-8894-14f5b793cbef'),('1071ee4f-a214-443f-8694-0b3e9d2dc77e'),
('120d2881-b04f-4707-a925-e4d941f03201'),('23af54a7-6666-4747-a74a-c2101cda59b0'),('260d2ce5-f4f0-4a0b-aa0b-3e1d2b5fcfeb'),
...
Select * from table where assessmentId IN(select value from #tt)

crystal report replace function

I have two tables:
Table 1:
Id stringval
-- ---------
1 do you work on date XXXX and date ####
Table 2:
Id CharString ValueString
-- ---------- -----------
1 XXXX 5-5-2013
2 #### 10-5-2013
I want to return the following string value:
do you work on date 5-5-2013 and date 10-5-2013
Can this be achieved using Crystal Reports?
Or, can it be achieved using Sql Server?
Assuming that XXXX, ####, or any other values in the CharString column of Table2 would only appear as placeholders it is also possible to achieve your goal using sql server. A query like this would do it:
DECLARE #CharString VARCHAR(100)
DECLARE #ValueString VARCHAR(100)
DECLARE #SearchString VARCHAR(100)
DECLARE #ResultString VARCHAR(100)
SELECT #SearchString = stringval FROM Table1
SELECT #ResultString = stringval FROM Table1
DECLARE c CURSOR FAST_FORWARD FOR
SELECT CharString, ValueString
FROM Table2
OPEN c
FETCH NEXT FROM c INTO #CharString, #ValueString
WHILE ##FETCH_STATUS = 0
BEGIN
IF PATINDEX('%' + #CharString + '%', #SearchString) <> 0
SET #ResultString = REPLACE(#ResultString, #CharString, #ValueString)
FETCH NEXT FROM c INTO #CharString, #ValueString
END
CLOSE c
DEALLOCATE c
SELECT #ResultString
The option here would be take the string value from table and manuplate the string the using string functions of crystal reports.
I am not sure how this will work but give a try.
take do you work on date XXXX and date #### into a string and split by space then extact XXXX and #### now take the required values 5-5-2013 and 10-5-2013 in to varaibles now join the strings like
"do you work on data "+5-5-2013+" and date "+10-5-2013

Column name as parameter and do sum on that in T Sql

My requirement is to send Columnname as Parameter to Stored procedure and do SUM on that Column.
I have written a small stored procedure to accept the column name as a parameter and do sum on that but I am getting an error with it.
CREATE PROCEDURE dbo.testCol
-- Add the parameters for the stored procedure here
#type as nvarchar(20),
#beginDate as smalldatetime,
#endDate as smalldatetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
select dbo.mytable.date, sum(#type) as quantity
from dbo.mytable
where dbo.mytable.Date between #beginDate AND #endDate
group by dbo.mytable.date,dbo.mytable.day
order by dbo.mytable.date
END
GO
I am getting the error as "Operand data type nvarchar is invalid for sum operator." while executing this stored procedure.
Any help much appreciated.
Thanks
You'll need to use dynamic sql to get the passed column name to be used this way in the query.
Use sp_executesql and include the column name in the string, and pass #beginDate and #endDate as parameters.
If you know the column names that are valid values, you can use CASE to avoid the evils of SQL Injection:
select dbo.mytable.date,
sum(case #type when 'QuantityColumn1' then QuantityColumn1
else QuantityColumn2 end ) as quantity
from dbo.mytable
where dbo.mytable.Date between #beginDate AND #endDate
group by dbo.mytable.date,dbo.mytable.day
order by dbo.mytable.date
If you must resort to dynamic SQL, validate your input so it can be trusted.
Yes, there is an easier way, Coolcake. Just cast the variable first like so:
CREATE TABLE FOO
(N VARCHAR(20))
SELECT * FROM DBO.FOO
INSERT INTO FOO VALUES('10')
INSERT INTO FOO VALUES('20')
INSERT INTO FOO VALUES('30')
INSERT INTO FOO VALUES('40')
INSERT INTO FOO VALUES('50')
SELECT SUM(CAST(N AS INT)) FROM FOO

How to determine internal name of table-valued variable in MS SQL Server 2005

The name of a temporary table such as #t1 can be determined using
select #TableName = [Name]
from tempdb.sys.tables
where [Object_ID] = object_id('tempDB.dbo.#t1')
How can I find the name of a table valued variable, i.e. one declared by
declare #t2 as table (a int)
the purpose is to be able to get meta-information about the table, using something like
select #Headers = dbo.Concatenate('[' + c.[Name] + ']')
from sys.all_columns c
inner join sys.tables t
on c.object_id = t.object_id
where t.name = #TableName
although for temp tables you have to look in tempdb.sys.tables instead of sys.tables. where do you look for table valued variables?
I realize now that I can't do what I wanted to do, which is write a generic function for formatting table valued variables into html tables. For starters, in sql server 2005 you can't pass table valued parameters:
http://www.sqlteam.com/article/sql-server-2008-table-valued-parameters
moreover, in sql server 2008, the parameters have to be strongly typed, so you will always know the number and type of columns.
Table variable metadata is viewable in tempdb.sys.tables too. This is easily verifiable from the below
declare #t2 as table ( [38F055D8-25D9-4AA6-9571-F436FE] int)
SELECT t.name, t.object_id
FROM tempdb.sys.tables t
JOIN tempdb.sys.columns c
ON t.object_id = c.object_id
WHERE c.name = '38F055D8-25D9-4AA6-9571-F436FE'
Example Results
name object_id
------------------------------ -----------
#4DB4832C 1303675692
But you will notice the object name is auto generated and bears no relation to the variable name.
If you do not have a guaranteed unique column name that you can use to filter on as above and the table variable has at least one row in it you can (from SQL Server 2008 onwards) use %%physloc%% and DBCC PAGE to determine this information. Example below.
DECLARE #t2 AS TABLE ( a INT)
INSERT INTO #t2
VALUES (1)
DECLARE #DynSQL NVARCHAR(100)
SELECT TOP (1) #DynSQL = 'DBCC PAGE(2,' + CAST(file_id AS VARCHAR) + ',' +
CAST( page_id AS VARCHAR) +
',1) WITH TABLERESULTS'
FROM #t2
CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
DECLARE #DBCCPage TABLE (
[ParentObject] [VARCHAR](100) NULL,
[Object] [VARCHAR](100) NULL,
[Field] [VARCHAR](100) NULL,
[VALUE] [VARCHAR](100) NULL )
INSERT INTO #DBCCPage
EXEC (#DynSQL)
SELECT VALUE AS object_id,
OBJECT_NAME(VALUE, 2) AS object_name
FROM #DBCCPage
WHERE Field = 'Metadata: ObjectId'
From Books Online:
A table variable behaves like a local variable. It has a well-defined scope, which is the function, stored procedure, or batch in which it is declared.
Given this, there should be no need to look up this value at run-time because you have to know it at design-time.
I don't believe you can, as table variables are created in memory not in tempdb.
On the topic of passing arbitrary lists/arrays into a SQL Server 2005 function or sproc, the least hokey way I know is to use an XML variable. If desired, that XML variable can be a strongly typed XML type that is associated w/ an XML Schema.
Given a list passed into a procedure/function as XML, you can extract that list into a table variable or temp table via "shredding".
"To shred" XML means to transform in the opposite direction--from XML to rowset(s). (The FOR XML clause causes a rowset to XML transformation.)
In the user-defined table function
CREATE FUNCTION [dbo].[udtShredXmlInputBondIdList]
(
-- Add the parameters for the function here
#xmlInputBondIdList xml
)
RETURNS
#tblResults TABLE
(
-- Add the column definitions for the TABLE variable here
BondId int
)
AS
BEGIN
-- Should add a schema validation for #xmlInputIssuerIdList here
--Place validation here
-- Fill the table variable with the rows for your result set
INSERT #tblResults
SELECT
nref.value('.', 'int') as BondId
FROM
#xmlInputBondIdList.nodes('//BondID') as R(nref)
RETURN
END
if the #xmlInputBondIdList is an XML fragment of the expected structure like that immediately below and is invoked as follows
DECLARE #xmlInputBondIdList xml
SET #xmlInputBondIdList =
'<XmlInputBondIdList>
<BondID>8681</BondID>
<BondID>8680</BondID>
<BondID>8684</BondID>
</XmlInputBondIdList>
'
SELECT *
FROM [CorporateBond].[dbo].[udtShredXmlInputBondIdList]
(#xmlInputBondIdList)
the result will be the rowset
BondId
8681
8680
8684
A couple other examples can be found at http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=678284&SiteID=1