oledb/ado.net: Get the command's text, with all parameters replaced - ado.net

Is it possible to get the text of an OleDbCommand with all parameters replaced with their values? E.g. in the code below I'm looking for a way to get the query text
SELECT * FROM my_table WHERE c1 = 'hello' and c2 = 'world'
after I finished assigning the parameters.
var query = "SELECT * FROM my_table WHERE c1 = ? and c2 = ?";
var cmd = new OleDbCommand(query, connection);
cmd.Parameters.Add("#p1", OleDbType.WChar).Value = "hello";
cmd.Parameters.Add("#p2", OleDbType.WChar).Value = "world";

No: you have to iterate through the parameters collection yourself, doing a string.Replace() to get the equivalent. It's particularly painful when you have to use the ? syntax rather than the #parametername syntax.
The reason for this is that the full string is never assembled. The parameters and sent to the server and treated as data, and are never included in the string.
All the same, I for one understand your pain. It would have been nice if they included some kind of .ComposeSQL() method you could call for debugging purposes, that perhaps also produces a compiler warning to help avoid use in production.

If you just need to see what query was executed and dont need to work with it programmatically, you can use SQL Profiler.

Related

How to use NOT IN statment in postgresql-rust

I am using the deadpool-postgres crate and actix-web in my application.
I am trying to do this:
let client: Client = db_pool.get().await.unwrap();
let mut interface_ids_to_keep :Vec<i32> = Vec::new();
// adding some ids to interface_ids_to_keep
client.execute("DELETE FROM interface WHERE host_id = $1 AND interface_id NOT IN $2", &[&host.host_id, &interface_ids_to_keep]).await.unwrap();
I always get the following sql error:
syntax error at or near "$2" at character 66
Seams like gets not replaced with the value (prepared statement style).
Do you have an idea how to use this feature?
Try NOT (interface_id = ANY($2)) where $2 is ToSql of a Vec / slice of whatever type interface_id is.
Often these simple array queries can have the same execution plan as their IN / NOT IN equivalents - but double check an EXPLAIN to be sure.

A cleaner way to pass many parameters into many functions in a script, without moving to object-oriented code structure?

I am looking for some style/best practice advice. I often find myself writing scripts which need many (several tens of) parameters to be defined at the beginning. Then these parameters are used by many functions within the script. A minimum, simplified example might look something like the following:
params.var1 = 1;
params.var2 = 10;
params.var3 = 100;
params.var4 = 1e3;
result1 = my_func1(params);
result2 = my_func2(params);
Now, I don't want to pass many inputs into every function, so am reluctant to do something like result1 = my_func1(var1,var2,var3,var4,...). Therefore, I always find myself making each variable a field of a structure (e.g. params), and then passing this structure alone into each function, as above. The structure is not modified by the functions, only the parameters are used for further calculations.
One of the functions might look like this then:
function result = my_func1(params)
var1 = params.var1;
var2 = params.var2;
var3 = params.var3;
var4 = params.var4;
result = var1.^2 + var2.^2 -var3.^3 + var4;
end
Now, because I don't want to refer to each variable within the function as params.var1, etc. (in the interest of keeping the expression for result as clear as possible), I first do all this unpacking at the beginning using var1 = params.var1.
I suppose the best thing to be doing in situations like this might be to use classes (because I have some data and also want to perform functions on that data). Are there any better ways for me to be doing this kind of thing without moving fully to object-oriented code?
I would simply leave the unpacking out. Call the struct params something shorter inside the function, to keep clutter to a minimum:
function result = my_func1(p)
result = p.var1.^2 + p.var2.^2 - p.var3.^3 + p.var4;
end
I would keep calling it params elsewhere, so you don’t have to deal with cryptic names.
You can define constant functions:
function out = var1
out = 1;
end
function out = var2
out = 10;
end
function result = my_func1
result = var1.^2 + var2.^2;
end
Based on your actual application you may pass array of numbers:
var = [var1 var2 var3 var4];
my_func1(var);
my_func1(var1,var2,var3,var4,...) in my opinion is preferred over passing struct.

Beginner-"Undefined function 'ReadIndexndexDailyLogreturn' for input arguments of type 'cell'."-Error

I am aware many of you will think this should be easily solvable. However, I have no clue about MATLAB.
Here goes my problem: when trying to execute the following example in the Command Window through the command
getLogReturnExcel('ALL.xls', {'ALL'}, 37000, 38000)
the cell-type error appears for this function. From what I understand however, when using {} the function should be grabbing the type inside {} (String in this case?) instead of the cell itself, which would be being grabbed if we were to use (), so there should be no error? Or is there something much more elementary that I might be overseeing? Thanks in advance for every bit of help; as you can tell I very much need it.
Cheers,
Ben
Here goes the function getLogReturnExcel:
function [logreturn, datearray] = getLogReturnExcel( datafilename, ticker, begindate, enddate )
[aanumber, aatext] = xlsread(datafilename);
aaticker = aatext(:,1);
aadate = aanumber(:,2);
aaret = zeros(length(aaticker),1);
aaret(1,1) = 0;
for i = 2:length(aaret)
aaret(i,1) = ln(aanumber(i,3))-ln(aanumber(i-1,3));
end
aadate = aadate(strcmp(aaticker,ticker));
aaret = aaret(strcmp(aaticker,ticker));
logreturn = aaret(aadate>=begindate & aadate<=enddate);
datearray = aadate(aadate>=begindate & aadate<=enddate);
return
The file 'ALL.xls' contains 3 columns, one with strings (the acronym for stocks) and two with numbers (I'm assuming double), one for the date in Excel-format and one with each day's stock standing.
The string can be obtained by using:
ticker{:}
or else the comparison in the lines
aadate = aadate(strcmp(aaticker,ticker));
aaret = aaret(strcmp(aaticker,ticker));
will be between strings and cell array.
Here is some documentation to access elements of a cell array.

Classic ASP - Insert SQL Statements - Which is better?

I have an insert that does not take any parameters.
which is a better way of doing things?
Set writeConn = Server.CreateObject("ADODB.Connection")
Call OpenConnect(writeConn)
Set objCommand = Server.CreateObject("ADODB.Command")
objCommand.ActiveConnection = writeConn
objCommand.CommandText = insstmt
objCommand.Execute()
writeConn.Close()
or
Set writeConn = Server.CreateObject("ADODB.Connection")
Call OpenConnect(writeConn)
writeConn.Execute(InsStmt)
writeConn.Close()
they seen to be doing the same thing...thank you!
They are equivalent. I would recommend you do it like this:
writeConn.Execute InsStmt,,adCmdText + adExecuteNoRecords
The adExecuteNoRecords parameter indicates that no data will be returned and avoids the creation of an (empty) recordset.
See here for more info.

In JDBC, how do I know when I am at the end of my FETCH?

I am following the example here
http://www.postgresql.org/docs/current/interactive/sql-fetch.html
And then looping the following command manually
FETCH FORWARD 5 FROM liahona;
in java. I have the above in an infinite loop and would like to know how I detect I'm at the end of the data set so I can break the loop
You get an empty result set when running FETCH FORWARD and you are at the end of the cursor's total result set. (This is described in slightly different words in the documentation.)
In use JDBC for this kind of SQL - it's for postgres command-line only.
For JDBC, you need something like this:
ResultSet rs = connection.createStatement().executeQuery("select * from mytable");
while(rs.next()) { // next() returns false if there are no more rows
int col1 = rs.getInt(1);
String col2 = rs.getString(2);
}