Maximo / BIRT - optional null values - sql

I'm trying to create a report in BIRT. I've created a stored proc in SQL Server 2008 which works perfectly. However, when I try to run the report in BIRT, it won't run with NULL value.
var DepartmentValue = params["DepartmentValue"].value;
var AccountValue = params["AccountValue"].value;
sqlText = " EXEC SP_Report_ByDept '"+DepartmentValue+"','"+AccountValue+"','"+startdt+"','"+enddt+"' ";
Works perfectly if there is a valid AcccountValue. Any idea how to pass null value for the AccountValue?
Cheers.

If I understand it correctly you want to pass the string 'null' when the actual parameter is null?
var DepartmentValue = params["DepartmentValue"].value;
var AccountValue = params["AccountValue"].value;
if (AccountValue == null){
AccountValue = 'null';
}
sqlText = " EXEC SP_Report_ByDept '"+DepartmentValue+"','"+AccountValue+"','"+startdt+"','"+enddt+"' ";

Related

How to set large string as param without getting ORA-01460: unimplemented or unreasonable conversion error?

In spring-boot using namedParameterJdbcTemplate (Oracle db version 12 and odbc8 driver 12.2)
I am getting the following error while executing a SELECT query bound with a parameter larger than 4000 character whereas update queries working fine.
ORA-01460: unimplemented or unreasonable conversion requested
The unit test I am trying to execute;
#Test
public void testSqlSelectQueryLargeStringParameter() {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("param", theLargeStr);
// #formatter:off
String sql =
"SELECT NULL id, NULL text FROM DUAL WHERE 'X' != :param ";
// #formatter:on
namedParameterJdbcTemplate.queryForRowSet(sql, params);
}
Is there any way to set this large param via MapSqlParameterSource?
I am #ahmet-orhan 's colleague, we've found a solution.
Thanks #kfinity for your suggestion, It is working for insert and update but we are still getting this error when we set clob or blob as "paremeter" in select statements.
If using a driver that supports JDBC4.0, the right solution is create a DefaultLobHandler and set streamAsLob or createTemporaryLob to true.
MapSqlParameterSource params = new MapSqlParameterSource();
String myString = "";
for (int i = 0; i < MAX_CLOB_BLOB_SIZE_IN_SELECT; i++) {
myString = myString + "1";
}
DefaultLobHandler lobHandler = new DefaultLobHandler();
lobHandler.setStreamAsLob(true);
params.addValue("param", new SqlLobValue(myString, lobHandler), Types.CLOB);
// #formatter:off
String sql =
"SELECT 1 id FROM DUAL WHERE :param IS NOT NULL ";
// #formatter:on
Integer id = namedParameterJdbcTemplate.queryForObject(sql, params, Integer.class);
We prefer streamAsLob but to be honest we have no idea which one is better.
This comment points out that ORA-01460 in JDBC queries is the same as "ORA-01704: string literal too long". (You can't have string literals longer than 4000 characters.) Maybe try this solution?
params.addValue("param", theLargeStr, Types.CLOB);
Although also != won't work for clob comparison, so you'll also need to change your query to
SELECT NULL id, NULL text FROM DUAL WHERE dbms_lob.compare('X',:param) != 0

MSSQL Returns Different result in SSMS and Node JS script

I have a SQL query to return customer's transaction header using customer's card_number. The SQL query will return a column called audit_number. The problem is the when i execute the SQL query using SSMS software, the query returns proper results, but when i execute the query on my Node JS script some of the audit_number are wrong.
The audit_number should be 14111990000015953 and 14111990000015952 but when i execute the query in my NODE JS script both audit_number become 14111990000015952.
Here is my sql query
SELECT
h.Log_trxdate AS trx_date,
CAST(h.log_audit AS varchar) AS audit_number,
h.currency_code
FROM log_header h
WHERE h.id_code = '10000010055919' --card_number
Here is my Node JS Script
var querySQL = " SELECT ";
querySQL = querySQL + " h.Log_trxdate AS trx_date, ";
querySQL = querySQL + " CAST(h.log_audit AS varchar) AS audit_number, ";
querySQL = querySQL + " FROM log_header h ";
querySQL = querySQL + " WHERE h.id_code = 10000010055919 ";
sql.connect(config, function (err) {
var req = new sql.Request();
req.query(querySQL, function (err, result) {
console.log(result);
});
});
You need to change your datatype number to varchar/text since in javascript if the number length is more than 16 digits then it will give you some random number.
So to get exact result you should change your Datatype from number to string.
For example if you check number
Number(1111111111111111)//16 digits
Result is 1111111111111111
But if you put Number(11111111111111111)//17 digits
then result will be 11111111111111112 something

How to build SELECT * WHERE using collection of conditions

I want to build a SELECT statement using a list of conditions that come from the query string of a REST api. I wrote this function, but maybe it is vulnerable to SQL injection. Can someone tell me if this is vulnerable how to fix it? Perhaps I should use some kind of SQLBuilder package? or is there a way to do it with just dotNet. I'm using dotNet 4.6.1
string BuildSelect(NameValueCollection query)
{
var result = "SELECT * FROM MYTABLE";
if (query.Count == 0) return result;
var logic = " WHERE ";
foreach (string key in query)
foreach (string v in query.GetValues(key))
{
result += logic + key + " = " + v;
logic = " AND ";
}
return result;
}
Yes it is vulnerable to SQL injection attack. You could build your query to use parameters instead (you are simply using an = check only).
Since you know the tablename, that means you also know what the columns (keys) can be. Thus, you could loop your columns, if the collection has that key then add it to the where as a parameterized statement BUT value part is NOT passed as a string, you parse it to the type it should be (or let the backend do the conversion and get error if cannot be converted). In pseudocode:
List<string> clauses = new List<string>();
var result = "SELECT * FROM MYTABLE";
foreach( var col in myTable.Columns )
{
if (query.ContainsKey(col.Name))
{
clauses.Add( $"{col.Name} = #{col.Name}";
string v = query[col.Name];
command.Parameters.Add( $"#{col.Name}", col.Type).Value = typeParse(v);
}
}
if (clauses.Any())
{
result += " WHERE " + string.Join( " AND ", clauses );
}
return result;
HTH

Dynamic SQL with servlets

I have a servlet called DBChart mapped to url /db.the servlet outputs some data based on the sql query used here.
What I have:
At client end, I am making an ajax call like this:
$.ajax({
type : 'POST',
async: false,
url : 'http://localhost:8080/DBCHART/db',
success : function(data) {/*some code*/})
and At server end, a static query that says:
String sql ="select * from Employee"
What I want:
I want to be able to pass some parameters here like :
url: http://localhost:8080/DBCHART/db?Name = 'xyz'?Age = 21
and at server end, the query in this case should become:
select * from Employee where Name ='xyz' and Age = 21
i.e only if those parameters were supllied otherwise it should stay
select * from Employee
Can I please get some direction to create dynamic sql for this efficiently?
let's say in this case you're using varName as 'xyz' and varAge as 21
-- -- Name = 'xyz'?Age = 21
you can use some logic like this (point to ponder: WHERE 1 = 1 )
string sqlQuery = " select * from Employee where 1 = 1 ";
if(null != varName && !varName.isEmpty())){
// add criteria for Name
sqlQuery += " AND Name = '"+ varName + "'"; // TODO: use parametrized query
}
if(null != varAge && varAge > 0){
// add criteria for Age
sqlQuery += " AND Age = "+ varAge ; // TODO: use parametrized query
}

Excel QueryTable Parameters do not bind Sql Parameters

I'm new in Excel development and I have an issue that It's driving me crazy. I hope you can help me.
Let me explain the situation,
I'm trying to create a QueryTable to import data from SQL , but ... I get an error at the moment to refresh the QueryTable,
the error message indicates that I'm not passing values for required parameters. ( It works hard coded :[ )
After many hours of investigation, I wasn't able to find a solution or an example to guide me... And here I am :|
I don't know what I'm doing wrong, Here is some code
foreach (Range row in main.Rows)
{
//row.Clear();
rowID = row.Row;
if (string.IsNullOrEmpty(getAccounts(rowID, columnID)) )
continue;
/* string connectionString = // \"
string.Format("OLEDB;Provider=SQLOLEDB;Data Source={0};Initial Catalog={1};User ID={2};Password={3}",
*/
//string sql = "EXECUTE [Funciones].[Cuenta_Saldo_Anho] ?,?";
//if (!string.IsNullOrEmpty(txtTipoSaldo.Text)) sql += ",?";
string sql = "{CALL [Funciones].[Cuenta_Saldo_Anho] (?, ?";
sql += (!string.IsNullOrEmpty(txtTipoSaldo.Text))? "" : ", ?" + ")}"; // optional parameter
var qt = wSheet.QueryTables.Add( connectionString, row.Cells , sql);
qt.CommandType = XlCmdType.xlCmdSql;
var ctas = qt.Parameters.Add("#ctas", XlParameterDataType.xlParamTypeLongVarChar);
//ctas.SetParam(XlParameterType.xlConstant, cuentas);
ctas.SetParam(XlParameterType.xlRange, wSheet.Cells[rowID, columnID]));
ctas.RefreshOnChange = true;
qt.Parameters.Add("#anho", XlParameterDataType.xlParamTypeInteger)
.SetParam(XlParameterType.xlConstant, Int32.Parse(anho));
qt.Parameters.Add("#tipoSaldo", XlParameterDataType.xlParamTypeVarChar)
.SetParam(XlParameterType.xlConstant, txtTipoSaldo.Text);
//qt.BackgroundQuery = true;
qt.FieldNames = false;
qt.AdjustColumnWidth = false;
qt.RefreshOnFileOpen = false;
qt.Refresh();
}
Any help is welcome. Thanks.