Multiple Search in SSRS when using only a part of the field - tsql

I Have created a stored procedure:
#DeviceID nvarchar(20) =''
WITH EXECUTE AS CALLER
AS
SELECT
amd.BRANDID,
amd.DEVICEID
FROM AMDEVICETABLE amd
where
left(amd.Deviceid,len(#DeviceID)) in (#DeviceID)
The length of amd.Deviceid is about 15 characters
In Visual Studio I create a parameter #DeviceID and when I am entering e.g ABCDE ( the first 5 characters from Deviceid) everything is working perfect.
the problem is that I want to put multiple values like
jhmcl*, jhmgd*.

So I created my own little version of your report and I believe the problem is your LEN() function. I'm surprised it doesn't return an error because it errors out in Report Builder for SQL Server 2014(simple version of SSRS). I would test what your LEN(#DeviceID) is returning. I would bet it's not returning the correct value. Instead you might try this to cover every possible pattern. I don't know how it will work performance wise.
SELECT DeviceID
FROM YourTable
WHERE LEN(DeviceID,1) IN (#DeviceID)
OR LEN(DeviceID,2) IN (#DeviceID)
OR LEN(DeviceID,3) IN (#DeviceID)
..
OR LEN(DeviceID,15),IN(#DeviceID)

Related

How to display a table which has a sorted dictionary in qstudio?

I have a table with a column which can sometimes contain strings and sometimes elements of the form `s#(`s#`timestamp$())!`symbol$(). However, whenever I run a select from the table using q studio, it gives the response (trueb;kx.c$Flip#eeaaafe;`sym1`sym2) even though it works perfectly fine in the q console. I tried disabling the wrapping but then it just gives the result ([] column_names).
Sample code:
q)([]col1:`row_1`row_2`row_3;col2:(118718;`s#`s#2018.04.04D07:30:00.000000000 2018.04.04D07:45:00.000000000!`value1`value2;`s#`s#2011.02.03D00:00:00.000000000 2018.06.06D00:00:00.000000000!123456 0N))
col1 col2
--------------------------------------------------------------------------------------
row_1 118718
row_2 `s#`s#2018.04.04D07:30:00.000000000 2018.04.04D07:45:00.000000000!`value1`value2
row_3 `s#`s#2011.02.03D00:00:00.000000000 2018.06.06D00:00:00.000000000!123456 0N
The reason this didn't work was that the java interface interprets the result as a different type when it's sorted. Perhaps this is fixed in newer API versions. Either way as Jonathon mentions it is fixed in qStudio version 1.43 and up.
If anyone else finds bugs please report to:
http://www.timestored.com/contact
As I don't always check SO.

How to insert similar value into multiple locations of a psycopg2 query statement using dict? [duplicate]

I have a Python script that runs a pgSQL file through SQLAlchemy's connection.execute function. Here's the block of code in Python:
results = pg_conn.execute(sql_cmd, beg_date = datetime.date(2015,4,1), end_date = datetime.date(2015,4,30))
And here's one of the areas where the variable gets inputted in my SQL:
WHERE
( dv.date >= %(beg_date)s AND
dv.date <= %(end_date)s)
When I run this, I get a cryptic python error:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) argument formats can't be mixed
…followed by a huge dump of the offending SQL query. I've run this exact code with the same variable convention before. Why isn't it working this time?
I encountered a similar issue as Nikhil. I have a query with LIKE clauses which worked until I modified it to include a bind variable, at which point I received the following error:
DatabaseError: Execution failed on sql '...': argument formats can't be mixed
The solution is not to give up on the LIKE clause. That would be pretty crazy if psycopg2 simply didn't permit LIKE clauses. Rather, we can escape the literal % with %%. For example, the following query:
SELECT *
FROM people
WHERE start_date > %(beg_date)s
AND name LIKE 'John%';
would need to be modified to:
SELECT *
FROM people
WHERE start_date > %(beg_date)s
AND name LIKE 'John%%';
More details in the pscopg2 docs: http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries
As it turned out, I had used a SQL LIKE operator in the new SQL query, and the % operand was messing with Python's escaping capability. For instance:
dv.device LIKE 'iPhone%' or
dv.device LIKE '%Phone'
Another answer offered a way to un-escape and re-escape, which I felt would add unnecessary complexity to otherwise simple code. Instead, I used pgSQL's ability to handle regex to modify the SQL query itself. This changed the above portion of the query to:
dv.device ~ E'iPhone.*' or
dv.device ~ E'.*Phone$'
So for others: you may need to change your LIKE operators to regex '~' to get it to work. Just remember that it'll be WAY slower for large queries. (More info here.)
For me it's turn out I have % in sql comment
/* Any future change in the testing size will not require
a change here... even if we do a 100% test
*/
This works fine:
/* Any future change in the testing size will not require
a change here... even if we do a 100pct test
*/

JasperReports: A dynamic table name using a variable? [duplicate]

This question already has an answer here:
Dynamic parameter of table name in Jasper [duplicate]
(1 answer)
Closed 3 years ago.
I have this problem with the JasperServer report I'm trying to create:
I have several db tables, named using a name and a date like this:
TABLE_NAME_YYYYMMDD
I want to be able to choose (and do a select from) the table which corresponds to the date submitted by the user from an ordinary Date input control.
I've tried creating a variable (called TABLE_NAME) which uses Java expressions for parsing the date like:
"MY_TABLE_" + new SimpleDateFormat("yyyyMMdd").format($P{RUN_DATE})
and when I print the value of the variable in the report it looks correct. But then I tried using that variable name in the SQL query like:
SELECT column1,column2.. from $V{TABLE_NAME}
but when I tried running the report in Jaspersoft Studio I got this Exception:
net.sf.jasperreports.engine.JRException: net.sf.jasperreports.engine.JRException: Error executing SQL statement for: my_report_x.
at com.jaspersoft.studio.editor.preview.view.control.ReportControler.fillReport(ReportControler.java:511)
at com.jaspersoft.studio.editor.preview.view.control.ReportControler.access$20(ReportControler.java:486)
So it doesn't seem to be working.
I read about the case when the whole table name can be specified in a parameter, and you're supposed to use:
$P!{tableName}
First I tried using that '!' with the variable name like:
..from $V!{TABLE_NAME}
but I got the same Exception.
Then I tried creating a new parameter instead, where "Is For Prompting" is Not checked, and as default value expression I put the same expression as I used in my variable:
"MY_TABLE_" + new SimpleDateFormat("yyyyMMdd").format($P{RUN_DATE})
but I still get the same error when I try to run the report in Jaspersoft Studio.
Does anyone know if there is a way to solve this? -Preferably a way that doesn't take several days to implement since I don't have that time.
I'm using Jaspersoft Studio 6.1.1.final and running the reports in JasperServer 5.5.0.
You should be able to get this to work by wrapping the whole of your FROM expression in the parameter e.g.
<parameter name="pTableName" class="java.lang.String">
<defaultValueExpression><![CDATA["from MY_TABLE_" + new SimpleDateFormat("yyyyMMdd").format($P{RUN_DATE})]]></defaultValueExpression>
</parameter>
And then using this in your SQL as a string literal:
SELECT column1,column2
$P!{pTableName}
WHERE 1 = 1
I just found out what I did wrong.
I admit it was rather stupid, but I only tried running the report in the Preview mode in Jaspersoft Studio. That's when I got the SQL error.
But I assume that the Preview mode does not support dynamic decisions about which table to read from, because when I ignored the Preview errors and published the report to JasperServer, I actually could run it there!
I ended up using the $P!{TABLE_NAME} parameter where the value is what I tried earlier:
"MY_TABLE_" + new SimpleDateFormat("yyyyMMdd").format($P{RUN_DATE})
I can print as much as possible of my SQL here (meaning that I have to replace names since this is a work report) if you want to see it:
select c.column1,c.column2, h.column3 from $P!{TABLE_NAME} h, TABLE2 i, TABLE3 p, TABLE4 ca, TABLE5 c
where h.P_ID = p.P_ID and h.A_ID = ca.A_ID and ca.C_ID = c.C_ID and ca.SOME_VALUE = 1 and ca.OTHER_VALUE = 1
and i.I_ID=h.I_ID
and i.OTHER_ID=1
and h.VALUE_X > 0
order by c.VALUE_Y
So my advice to others who create Jasper reports is not to let yourselves get fooled by the fact that some things don't work in Preview mode. -That might just be the "preview limitations".

SSRS Reports Versioning

I'm looking for a way to get versioning informations out of my SSRS reports. I have several environments and would like to be able to compare which report version is deployed on these environments. In SSIS this is very easy because each SSIS package gets a new version when it was modified and safed. Is there something similiar with the reports ?
Unfortunately there currently is no built-in functionality similar to a dll assembly version for RDL files.
The only way to get some kind of version information is to query the last modified date of the RDL file on the server via C# or VB.Net. You could do this using the ReportingServices webservice.
You could also implement a custom function which updates some field in your database to the current date each time the RDL file modified.
The problem with all the file modified information: You still don't know which version is on which server, you just know when it was uploaded/modified.
See the following pages for some more information - unfortunately no solution:
SSRS 2005 Can I dynamically determine when .rdl file was last modified
.RDL "Version" properties like in ".DTSX" files
In my reports, I create a variable named Version and make it a string data type (and move it to the top of the variable list). Every time I change a report, I update the Version variable based on Semantic Versioning.
Then, I can query my Report Server and look at the Parameter field of the ExecutionLog table and I can see what version was run. Technically I take care of all of this in an SSIS job that writes to another table, but that's a little outside the scope here.
There still seems to be no good solution.
If you create a hidden Parameter "Version" with a default value you could use a build Task to modify its value in the .rdl file, e.g. the revision part with the source control changeset number.
Sadly you may need another visual Studio Project to place this build task since the reporting project type seems not capable.
You may also create inline code or an assembly that may do some lookup.
Cheap suboptimal alternative:
Use the last modified date form the report database:
Select
Name,
Path,
CreationDate,
ModifiedDate,
ModUser.UserName AS ModUser,
CAST(catalog.parameter as xml).value(/Parameters[1]/Parameter[Name="Version"][1]/Values[1]/Value[1]','NVARCHAR(20)') as Version
FROM Reportserver.dbo.Catalog
INNER JOIN ReportServer.dbo.Users ModUser on Moduser.UserID = ModifiedByID
WHERE Type = 2
and convert the date to a revision number...
Doesen't help with versions across different server instances though.
The Report Server dbo.Catalog table has both CreationDate and ModifiedDate.
As part of an investigation I put together a query to list out the queries in RDL files and perform a simple CHECKSUM on that to facilitate checking for drift.
You can of course do the same on the whole of Content field much more simply, or do a better job of opening the XML using real xml processing.
Hope it is helpful;
DECLARE #reftextstart VARCHAR(255);
DECLARE #reftextend VARCHAR(255);
SELECT #reftextstart = '%<CommandText>%';
SELECT #reftextend = '</CommandText>';
SELECT SQ2.Path,
SQ2.Name,
SQ2.CreationDate,
SQ2.ModifiedDate,
ReportQuery,
CHECKSUM(ReportQuery) ReportQueryChecksum
FROM
(
SELECT SQ.Path,
SQ.Name,
SQ.CreationDate,
SQ.ModifiedDate,
CASE PATINDEX(#reftextstart, Report)
WHEN 0 THEN
N''
ELSE
SUBSTRING(
Report,
PATINDEX(#reftextstart, Report) + LEN(#reftextstart) - 2,
CHARINDEX(
#reftextend,
SUBSTRING(
Report,
PATINDEX(#reftextstart, Report) + LEN(#reftextstart) - 2,
1024
)
) - 1
)
END ReportQuery
FROM
(
SELECT TOP 1000
[Path],
[Name],
[CreationDate],
[ModifiedDate],
[ExecutionTime],
CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), Content)) Report
FROM [ReportServer].[dbo].[Catalog]
WHERE Name IN ( N'Report1', N'Report2' )
) SQ
) SQ2
ORDER BY [Path],
Name;
I tried this solution for my customers:
Open the .rdl file with notepad and add a comment in the first line and save it, like:
<?xml version="1.0" encoding="utf-8"?>
<!--
=============================================
Author: My Name (My Company)
CHANGE date: Release Date
Description: Short description
Current Version: Ver x.x.x
Vx.x.x: Version change history
=============================================
-->
<Report MustUnderstand="df" xmlns=...
I hope it helps others

Can the Sequence of RecordSets in a Multiple RecordSet ADO.Net resultset be determined, controlled?

I am using code similar to this Support / KB article to return multiple recordsets to my C# program.
But I don't want C# code to be dependant on the physical sequence of the recordsets returned, in order to do it's job.
So my question is, "Is there a way to determine which set of records from a multiplerecordset resultset am I currently processing?"
I know I could probably decipher this indirectly by looking for a unique column name or something per resultset, but I think/hope there is a better way.
P.S. I am using Visual Studio 2008 Pro & SQL Server 2008 Express Edition.
No, because the SqlDataReader is forward only. As far as I know, the best you can do is open the reader with KeyInfo and inspect the schema data table created with the reader's GetSchemaTable method (or just inspect the fields, which is easier, but less reliable).
I spent a couple of days on this. I ended up just living with the physical order dependency. I heavily commented both the code method and the stored procedure with !!!IMPORTANT!!!, and included an #If...#End If to output the result sets when needed to validate the stored procedure output.
The following code snippet may help you.
Helpful Code
Dim fContainsNextResult As Boolean
Dim oReader As DbDataReader = Nothing
oReader = Me.SelectCommand.ExecuteReader(CommandBehavior.CloseConnection Or CommandBehavior.KeyInfo)
#If DEBUG_ignore Then
'load method of data table internally advances to the next result set
'therefore, must check to see if reader is closed instead of calling next result
Do
Dim oTable As New DataTable("Table")
oTable.Load(oReader)
oTable.WriteXml("C:\" + Environment.TickCount.ToString + ".xml")
oTable.Dispose()
Loop While oReader.IsClosed = False
'must re-open the connection
Me.SelectCommand.Connection.Open()
'reload data reader
oReader = Me.SelectCommand.ExecuteReader(CommandBehavior.CloseConnection Or CommandBehavior.KeyInfo)
#End If
Do
Dim oSchemaTable As DataTable = oReader.GetSchemaTable
'!!!IMPORTANT!!! PopulateTable expects the result sets in a specific order
' Therefore, if you suddenly start getting exceptions that only a novice would make
' the stored procedure has been changed!
PopulateTable(oReader, oDatabaseTable, _includeHiddenFields)
fContainsNextResult = oReader.NextResult
Loop While fContainsNextResult
Because you're explicitly stating in which order to execute the SQL statements the results will appear in that same order. In any case if you want to programmatically determine which recordset you're processing you still have to identify some columns in the result.