How to see HQL final query - sql-server

I'm trying to run the following query and getting a null pointer exception. I've verified that WHERE lockedTimestamp <= (GETDATE() - CAST('00:06' AS datetime) is valid msSQL because I can run it manually and it'll work fine. It appears HQL (Hibernate Query Language) may not like it. Any thoughts on how I can go about debugging this?
Query query = this.em.createQuery("SELECT c FROM Content c WHERE lockedTimestamp <= (GETDATE() - CAST('00:06' AS datetime))");

Why not use a much more obvious and intuitive calculation, e.g.
SELECT c FROM Content c WHERE lockedTimestamp <= DATEADD(MINUTE, -6, GETDATE());
? I gather this isn't valid in JPQL either, but more for the general query itself in case other users stumble across this question...
As an aside, why not put this query in a stored procedure? Surely hibernate can call a stored procedure, then it doesn't need to try to interpret or reverse engineer your query.

EntityManager.createQuery expects a query string in JPQL (not HQL, and not SQL). JPQL does not define a CAST function.
I'd compute the timestamp limit in Java, and pass it as parameter to the query:
Date limit = ...;
this.em.createQuery("SELECT c FROM Content c WHERE lockedTimestamp <= ?")
.setParameter(0, limit);

To debug sql, you can show the queries that launches Hibernate by adding the configuration hibernate.show_sql=true in the hibernate configuration properties.
The queries will be shown in console, and it's the exact query that hibernate make to the database.

Related

How does the question mark function in the SQL query?

I'm attempting to edit an ETL package(SSIS) that queries a SQL table and outputs csv files for every StationID and I'm having trouble understanding how the question mark is being used in the query definition below. I understand ? is used a parameter but I don't understand how it's used in the date function below:
SELECT TimeSeriesIdentifier, StationID, ParameterID FROM dbo.EtlView WHERE
LastModified > DATEADD(hour, ?*-1, GETDATE())
AND StationID LIKE
CASE WHEN ? = 0 THEN
StationID
ELSE
?
END
The parameterization available in SSIS is dependent upon the connection manager used.
OLE DB and ODBC based connection managers use ? as the variable place holder, whereas ADO.NET uses a named parameter, #myVariable.
OLE DB begins counting at 0 whereas ODBC used a 1 based counting system. They are both however ordinal based systems so in your CASE expression the two ? are for the same variable. But, you'll have to list that SSIS Variable twice in the parameter mapping dialog because it's ordinal based - i.e. (param, name) => #HoursBack, 0; #MyVar, 1; and #MyVar, 2;
A "dumb trick" I would employ if I had to deal with repeated ordinal based parameters or if I was troubleshooting packages is to make the supplied query use local variables in the query itself.
DECLARE
#HoursBack int = ?
, #MyVariable int = ?;
SELECT
TimeSeriesIdentifier
, StationID
, ParameterID
FROM
dbo.EtlView
WHERE
LastModified > DATEADD(HOUR, #HoursBack * -1, GETDATE())
AND StationID LIKE
CASE
WHEN #MyVariable = 0 THEN StationID
ELSE #MyVariable
END;
Now I only have to map the SSIS Variable #MyVar once into my script as the "normal" TSQL parameterization takes over. The other benefit is that I can copy and paste that into a query tool and sub in the ?s with actual values to inspect the results directly from the source. This can be helpful if you're running into situations where the strong typing in SSIS prevents you from getting the results into a data viewer.
SSIS is building a parameterized query.
You can get more information about this here (MySQL-specific):
What is the question mark's significance in MySQL at "WHERE column = ?"?
Or you can get a more generally-applicable response here: What does a question mark represent in SQL queries?
At a very "nuts and bolts" level, those are parameters being passed into the SQL statement by the package. With the Execute SQL task open, click on the tab that says Parameter Mapping. There will be a list of variables that are being sent into the query, and they are consumed in the order that they're listed.
Here's a logger for an archiving package I'm working on:
The query on the General tab just writes those five values to a table:
INSERT INTO dbo.ArchiveRowCounts (
TableName,
ServerName,
ReportYear,
BaseTblCnt,
ArchiveTblCnt)
VALUES (?,?,?,?,?);

Hard code SSRS multi value parameter for testing

I'm trying to test a SQL query in SQL Server Management Studio that normally requires a multivalue parameter from the SSRS report its a part of.
I'm not sure to how hard code a multi value parameter in management studio. The report was created by a vendor, I'm just trying to make it runnable for testing outside of SSRS.
For example the parameter in SSRS is a collection of numbers that the user selects - ie "3100, 3102, 3105" would be the selections for the multivalue parameter called #object_code
I've got something like this - but it's not working.
Declare #Object_Code varchar(100)
Set #object_Code = ('3100','3102','3105')
....really long vendor written query I don't thoroughly understand...
IN(#object_code)
You have to use String-Split function to separate comma separated values.
For example-
Declare #Object_Code varchar(100)
Set #Object_Code = '3100,3102,3105'
....really long vendor written query I dont thoroughly understand...
--T.object_code IN (#object_code)
Inner Join dbo.Split(#Object_Code, ',') as S On S.data = T.object_code
Search your database first for any string-split function.
If you want to create string-split function then follow this -
T-SQL split string
If you use SQL Server 2016 you might want to check out the function STRING_SPLIT.
If you use a lower version of SQL Server and you can't or don't want to create a separate function, the following could be an alternative:
declare #object_code varchar(100);
set #object_code = '3100,3102,3105';
select
ltrim(rtrim(x.par.value('.[1]','varchar(max)'))) as object_code
from (
select convert(xml,'<params><param>' + replace(#object_code,',', '</param><param>') + '</param></params>') as c
) tbl
cross apply
c.nodes('/params/param') x(par);
Everybody seems to be getting hung up on splitting a string that doesn't have to be a string. We're just trouble shooting a query here and need a way to feed it values. It's not important how SSRS does it, just that we can reproduce the result.
Declare #Object_Code table (params varchar(20));
INSERT #object_Code
VALUES ('3100'),('3102'),('3105')
....really long vendor written query I don't thoroughly understand...
IN (SELECT params FROM #object_code)
Then spend some quality time getting to know the query.

How to write a parameterized SQL query?

I am trying this query to fetch my value from a MS SQL database on basis of two conditions but still I am getting exception in the syntax part.
Can anybody tell me what is the correct way to write a parameterized query in R?
Following is the query I used:
query<- paste0("SELECT [value] FROM [RiskDashboard].[dbo].[tbl_Simulation]
where Row_Id=", row_id[c(1),] ," AND Script_Id=", script_id[c(1),] ,)
T_data<-sqlQuery(ch,query)
print(T_data)
Parameterizing data is very important - especially from a security perspective. The examples you have are string concatenations and are subject to SQL injections.
The RODBCext package does have support for parameterization.
First - standard SQL parameterization syntax:
SELECT ColA, ColB FROM MyTable where FirstName = ? and LastName = ?
Each ? mark indicates in order the values that will appear in a vector. This syntax is true for ODBC regardless of platform. Others have extended to support position. eg. OLEDB supports #P1, #P2 etc.
While maybe not important for your R queries - in a multi-user system parameterized queries execute faster because the query plan is stored by the database-server (true of both Oracle and SQL Server).
To semi-plagiarize from the documentation:
library(RODBCext)
connHandle <- odbcConnect("myDatabase")
data <- sqlExecute(connHandle, "SELECT * FROM myTable WHERE column = ?", 'myValue', fetch = TRUE)
odbcClose(connHandle)
Documentation is here: https://cran.r-project.org/web/packages/RODBCext/vignettes/Parameterized_SQL_queries.html
More discussion here: Parameterized queries with RODBC
i got the correct way as follows:
query<- paste0("SELECT [Row_Id],[Script_id],[value] FROM
[RiskDashboard].[dbo]. [tbl_Simulation] where Row_Id='",row_id[c(i),],"'
AND Script_Id='",script_id[c(i),],"'")

Hibernate JPQL CURRENT_DATE not working on SQL Server

I have the following JPQL query:
SELECT x FROM Bla x WHERE x.deadline < CURRENT_DATE
This works as expected on MySQL. But SQL Server complains that CURRENT_DATE is not recognized.
I am asking myself what exactly the problem is. Then CURRENT_DATE is a standard JPA function that should resolve independent from the underlying RDBMS.
Further the Hibernate documentation also has CURRENT_DATE documented (see here: http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch11.html#ql-expressions).
I googled and found a lot fo comments telling me that I shall use CURRENT_DATE() instead. But this isn't JPQL.
So why is CURRENT_DATE not working and what is the solution?
I am using Hibernate 4.1.8.Final.
Best regards,
Florian
You can try to pass current date as a parameter to the query. Also, there will no portability issue whith this.
session.createQuery("SELECT x FROM TABLE_NAME x WHERE x.deadline < :currentDate")
.setParameter( "currentDate", currentDate)
.list();
Else, you can try query with current_date() instead of current_date, which is part of HQL expression.
try using GETDATE()
SELECT x FROM Bla x WHERE x.deadline < GETDATE()

Declaring temporary variables in PostgreSQL

I'm migrating from SQL Server to PostgreSQL. I've seen from How to declare a variable in a PostgreSQL query that there is no such thing as temporary variables in native sql queries.
Well, I pretty badly need a few... How would I go about mixing in plpgsql? Must I create a function and then delete the function in order to get access to a language? that just seems error prone to me and I'm afraid I'm missing something.
EDIT:
cmd.CommandText="insert......" +
"declare #app int; declare #gid int;"+
"set #app=SCOPE_IDENTITY();"+ //select scope_identity will give us our RID that we just inserted
"select #gid=MAX(GROUPID) from HOUSEHOLD; set #gid=#gid+1; "+
"insert into HOUSEHOLD (APPLICANT_RID,GROUPID,ISHOH) values "+
"(#app,#gid,1);"+
"select #app";
rid=cmd.ExecuteScalar();
A direct rip from the application in which it's used. Note we are in the process of converting from SQL server to Postgre. (also, I've figured out the scope_identity() bit I think)
What is your schema for the table being inserted? I'll try and answer based on this assumption of the schema:
CREATE TABLE HOUSEHOLD (
APPLICANT_RID SERIAL, -- PostgreSQL auto-increment
GROUPID INTEGER,
ISHOH INTEGER
);
If I'm understanding your intent correctly, in PostgreSQL >= 8.2, the query would then be:
INSERT INTO HOUSEHOLD (GROUPID, ISHOH)
VALUES ((SELECT COALESCE(MAX(GROUPID)+1,1) FROM HOUSEHOLD), 1)
RETURNING APPLICANT_RID;
-- Added call to the COALESCE function to cover the case where HOUSEHOLD
-- is empty and MAX(GROUPID) returns NULL
In PostgreSQL >= 8.2, any INSERT/DELETE/UPDATE query may have a RETURNING clause that acts like a simple SELECT performed on the result set of the change query.
If you're using a language binding, you can hold the variables there.
For example with SQLAlchemy (python):
my_var = 'Reynardine'
session.query(User.name).filter(User.fullname==my_var)
If you're in psql, you have variables:
\set a 5
SELECT :a;
And if your logic is in PL/pgSQL:
tax := subtotal * 0.06;
Must I create a function and then
delete the function in order to get
access to a language?
Yes, but this shortcoming is going to be removed in PostgreSQL 8.5, with the addition of DO command. 8.5 is going to be released in 2010.
You can also declare session variables using plperl - http://www.postgresql.org/docs/8.4/static/plperl-global.html
you install a language that you want to use with the CREATE LANGUAGE command for known languages. Although you can use other languages.
Language installation docs
CREATE LANGUAGE usage doc
You will have to create a function to use it. If you do not want to make a permanent function in the db then the other choice would be to use a scrip in python or something that uses a postgresql driver to connect to the db and do queries. You can then manipulate or look through the data in the script. For instance in python you would install the pygresql library and in your script import pgdb which you can use to connect to the db.
PyGreSQL Info
I think that PostgreSQL's row-type variable would be the closest thing:
A variable of a composite type is
called a row variable (or row-type
variable). Such a variable can hold a
whole row of a SELECT or FOR query
result, so long as that query's column
set matches the declared type of the
variable.
You mentioned the post (How to declare a variable in a PostgreSQL query).
I believe there is a suitable answer farther down the chain of solutions if using psql and the \set command:
my_db=> \set myvar 5
my_db=> SELECT :myvar + 1 AS my_var_plus_1;

Resources