How to evaluate parameter variable stored in a file in jMeter? - sql

Say, I have a jMeter variable var equals 123.
I also have a query stored in a sql file:
SELECT * FROM Table WHERE ID = ${var}
All I need is to read that query from the file and evaluate ${var} into actual value, and then execute it in JDBC Sampler. So I need to combine these two pieces into
SELECT * FROM Table WHERE ID = 123
and pass the query to JDBC sampler.
Though, jMeter doesn't evaluate the ${var} parameter stored in that sql file and all I can pass to JDBC sampler is (obvious one):
SELECT * FROM Table WHERE ID = ${var}.
Does anyone know how to make jMeter evaluate the stored variable into actual value?

I had a similar requirement.
You need to use Beanshell Preprocessor for the JDBC sampler. Copy the below script and put it in a .bsh file and call it. I assumed you have the query stored in 'SQLQuery' variable.
I tested the below script and it works.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
String regex = "\\$\\{([^}]+)\\}";
SQLQuery = vars.get("SQLQuery");
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(SQLQuery);
while(matcher.find())
{
String token = matcher.group(); //${var}
String tokenKey = matcher.group(1); // var
SQLQuery = SQLQuery.replaceFirst(Pattern.quote(token), Matcher.quoteReplacement(vars.get(tokenKey)));
}
vars.put("SQLQuery", SQLQuery);

You need to use a "Prepared Select Statement" as Query Type. Prepared Statements
Then replace your ${var} with ?
SELECT * FROM Table WHERE ID = ?
And add the 2 parameters at the bottom.
Parameter values: ${var}
Parameter types: INT

Related

Bigquery named parameters regex in Java

I am looking for a way to use a regex as value in a named parameter in the Java SDK. According to the documentation, there is no datatype for that, and using a String parameter does not work.
Is there any way to use a regex as value in a named parameter?
QueryParameterValue Class has no datatype for that:
https://googleapis.dev/java/google-cloud-clients/0.91.0-alpha/com/google/cloud/bigquery/QueryParameterValue.html#of-T-com.google.cloud.bigquery.StandardSQLTypeName-
A regex in the query would e.g. look like this:
REGEXP_CONTAINS(some_attribute, r"^any\sregex\ssearchstring$")
and should be replaced by a named parameter like:
REGEXP_CONTAINS(some_attribute, #named_regex_parameter)
I tried different syntax in the query like
REGEXP_CONTAINS(some_attribute, r#named_regex_parameter)
etc. but none of them worked. The #named_regex_parameter is of type String. I tried to use values in the form of r"regex_expression" and just the regex_expression in the parameter value.
Seems like I need to build the query String without a named parameter for the regex part. Any hints to solve this with parameters would be really appreciated!
//Edit: added code example how the named parameters are used in the query config
QueryJobConfiguration queryConfig = QueryJobConfiguration.newBuilder(query)
.setDestinationTable(TableId.of(destinationDataset, destinationTable))
.setAllowLargeResults(true)
.setCreateDisposition(CreateDisposition.CREATE_IF_NEEDED)
.setTimePartitioning(partitioning)
.setWriteDisposition(WriteDisposition.WRITE_APPEND)
.setParameterMode("NAMED")
.addNamedParameter("regexExpressionParam", QueryParameterValue.string(someRegexExpressionStringVariable)) //this does not work
.addNamedParameter("someStringParam", QueryParameterValue.string(stringVariable))
.setPriority(Priority.BATCH)
.build();
The query should use the parameter #regexExpressionParam like so:
REGEXP_CONTAINS(theAttributeToQuery, #regexExpressionParam))
You need to pass the regular expression string without r'...'
I had a very similar problem with running parameterized queries on Python: it was something like this.
from google.cloud import bigquery
regex_input = "^begin_word.*end_here$"
# Construct a BigQuery client object.
client = bigquery.Client()
query = """
SELECT word, word_count
FROM `bigquery-public-data.samples.shakespeare`
WHERE REGEXP_CONTAINS(word, #regex)
ORDER BY word_count DESC;
"""
job_config = bigquery.QueryJobConfig(
query_parameters=[
bigquery.ScalarQueryParameter("regex", "STRING", f"r'{regex_input}'"),
]
)
query_job = client.query(query, job_config=job_config)
At first, I thought the input had to be wrapped by r'...'; just like how I normally write a regex on BQ explorer.
I tried to modify the string input to make it like a regular expression, which was this pard f"r'{regex_input}'" of the code.
but apparently BQ correctly escapes string without our help and I can just pass down the regex string like bigquery.ScalarQueryParameter("regex", "STRING", regex_input)

ruby variable inside sql statement

I am trying to use a ruby variable inside an sql statement. The following code works and deletes the second record of the templates table. How do i replace this number with my user defined variable "deleteid"?
deleteid = gets.chomp
$db.execute %q{DELETE FROM templates
WHERE id = 2}
You can use string interpolation:
$db.execute %{DELETE FROM templates WHERE id = #{deleteid}}
$db.execute %Q{DELETE FROM templates WHERE id = #{deleteid}}
UPDATE
User can pass arbitrary string. Using deleteid directly can be dangerous. As #muistooshort commented, you should escape the deleteid.
Consult your db driver's documentation for methods that accepts parameter and escape the parameter (or prepare method).
For example, if you use sqlite3-ruby, you can use Database#query, which will escape for you.
$db.prepare(%q{DELETE FROM templates WHERE id = ?}, [deleteid])
in pg, use Connection#exec_params:
$db.exec_params(%q{DELETE FROM templates WHERE id = $1}, [deleteid])

Groovy SQL Multiple ResultSets

I am calling a stored procedure from my Groovy code. The stored proc looks like this
SELECT * FROM blahblahblah
SELECT * FROM suchAndsuch
So basically, two SELECT statements and therefore two ResultSets.
sql.eachRow("dbo.testing 'param1'"){ rs ->
println rs
}
This works fine for a single ResultSet. How can I get the second one (or an arbitrary number of ResultSets for that matter).
You would need callWithAllRows() or its variant.
The return type of this method is List<List<GroovyRowResult>>.
Use this when calling a stored procedure that utilizes both output
parameters and returns multiple ResultSets.
This question is kind of old, but I will answer since I came across the same requirement recently and it maybe useful for future reference for me and others.
I'm working on a Spring application with SphinxSearch. When you run a query in sphinx, you get results, you need to run a second query to get the metadata for number of records etc...
// the query
String query = """
SELECT * FROM INDEX_NAME WHERE MATCH('SEARCHTERM')
LIMIT 0,25 OPTION MAX_MATCHES=25;
SHOW META LIKE 'total_found';
"""
// create an instance of our groovy sql (sphinx doesn't use a username or password, jdbc url is all we need)
// connection can be created from java, don't have to use groovy for it
Sql sql = Sql.newInstance('jdbc:mysql://127.0.0.1:9306/?characterEncoding=utf8&maxAllowedPacket=512000&allowMultiQueries=true','sphinx','sphinx123','com.mysql.jdbc.Driver')
// create a prepared statement so we can execute multiple resultsets
PreparedStatement ps = sql.getConnection().prepareStatement(query)
// execute the prepared statement
ps.execute()
// get the first result set and pass to GroovyResultSetExtension
GroovyResultSetExtension rs1 = new GroovyResultSetExtension(ps.getResultSet())
rs1.eachRow {
println it
}
// call getMoreResults on the prepared statement to activate the 2nd set of results
ps.getMoreResults()
// get the second result set and pass to GroovyResultSetExtension
GroovyResultSetExtension rs2 = new GroovyResultSetExtension(ps.getResultSet())
rs2.eachRow {
println it
}
Just some test code, this needs some improving on. You can loop the result sets and do whatever processing...
Comments should be self-explanatory, hope it helps others in the future!

SSIS filename - file count

I'm currently creating a flat file export for one of our clients, i've managed to get the file in the format they want, i'm trying to get the easiest way of creating a dynamic file name. I've got the date in as a variable and the path ect but they want a count in the file name. For example
File name 1 : TDY_11-02-2013_{1}_T1.txt. The {} being the count. So next weeks file would be TDY_17-02-2013_{2}_T1.txt
I cant see an easy way of doing this!! any idea's??
EDIT:
on my first answer, I thought you meant count of values returned on a query. My bad!
two ways to achieve this, you could loop into the destination folder, select the last file by date, get its value and increase 1, which sound like a lot of trouble. Why not a simple log table on the DB with last execution date and ID and then you compose your file name base on the last row of this table?
where exactly is your problem?
you can make a dynamic file name using expressions:
the count, you can use a "row count" component inside your data flow to assign the result to a variable and use the variable on your expression:
Use Script task and get the number inside the curly braces of the file name and store it in a variable.
Create a variable(FileNo of type int) which stores the number for the file
Pseudo code
string name = string.Empty;
string loction = #"D:\";
/* Get the path from the connection manager like the code below
instead of hard coding like D: above
string flatFileConn =
(string(Dts.Connections["Yourfile"].AcquireConnection(null) as String);
*/
string pattern = string.Empty;
int number = 0;
string pattern = #"{([0-9])}"; // Not sure about the correct regular expression to retrieve the number inside braces
foreach (string s in Directory.GetFiles(loction,"*.txt"))
{
name = Path.GetFileNameWithoutExtension(s);
Match match = Regex.Match(name, pattern );
if (match.Success)
{
dts.Variables["User::FileNo"].Value = int.Parse(match.Value)+1;
}
}
Now once you get the value use it in your file expression in the connection manager
#[User::FilePath] +#[User::FileName]
+"_{"+ (DT_STR,10,1252) #[User::FileNo] + "}T1.txt"

Use arguments value in sql statements

I am using jsp-jdbc and I want to use the value of a argument in sql statements.
For eg: http://localhost:3232/file.jsp?name="as"
In the jsp file containing jsp I want:
select * from books where name= (the value of argument 'name' in the url)
How will it do?
You can use HttpServletRequest#getParameter() to get the request parameter.
String name = request.getParameter("name");
// ...
You can use PreparedStatement#setXxx() to set an user-definied variable in a SQL string.
preparedStatement = connection.prepareStatement("SELECT * FROM books WHERE name=?");
preparedStatement.setString(1, name);
resultSet = preparedStatement.executeQuery();
// ...
Note that this job doesn't belong in a JSP, but in a Servlet (with a service/DAO class).
See also:
Advanced Servlets/JSP tutorial
JDBC tutorial - Prepared statements