.NET ODBC Oracle Params getting param name returned by db provider- possible? - vb.net

I'm converting some RDO code to ODBC Provider code in .NET.
The problem is parameter names were not specified in the orignal code, but param values were retrieved by parameter name after the command was executed.
Is there anyway to have parameter names populated by the provider once the command is executed so calling code can access params by name.
Let me show you an example of the declaration of param and accessing of it.
With rdqryClntBasic
.Parameters.Add(.CreateParameter) : .Parameters(0).Direction = ParameterDirection.Input
.Parameters(0).DbType = DbType.String
.Parameters(0).Value = sClntProdCd
End With
.EffectiveDate = ToDate(rdqryClntBasic.Parameters("dtEffDt").Value)
You can now see how this "used to work in RDO/VB". For some reason it would accept this and know what the param names were after execution. I imagine it had to do another round trip to the db to get this info.
Is there anyway to mimic this behaviour in .NET for ODBC Provider (using Oracle)? Or am I stuck manually specifying the param names in the code (I understand this is the better option, but wondering what the alternative is to match the original code as closely as possible).

No, parameters in ODBC are positional not by name.

Related

npgsql executescalar() allways returns nothing

I'm using npgsql as a nuget package in visual studio 2017 with visual basic.
Various commands do work very well but an ExecuteScalar allways returns 'nothing' although it should give a result.
The command looks like this:
Dim ser As Integer
Dim find = New NpgsqlCommand("SELECT serial from dbo.foreigncode WHERE code = '#code';", conn)
Dim fcode = New NpgsqlParameter("code", NpgsqlTypes.NpgsqlDbType.Varchar)
find.Parameters.Add(fcode)
find.Prepare()
fcode.Value = "XYZ"
ser = find.ExecuteScalar() ==> nothing
When the command string is copied as a value during debugging and pasted into the query tool of PGADMIN it delivers the correct result. The row is definitely there.
Different Commands executed with ExecuteNonQuery() work well, including ones performing UPDATE statements on the row in question.
When I look into the properties of the parameter fcode immediately before the ExecuteScalar it shows 'fcode.DataTypeName' caused an exception 'System.NotImplementedException'.
If I change my prepared statement to "SELECT #code" and set the value of the parameter to an arbitrary value just this value is returned. There is no access to the table taking place because the table name is not part of the SELECT in this case. If I remove the WHERE CLAUSE in the SELECT and just select one column, I would also expect that something has to be returned. But again it is nothing.
Yes there is a column named serial. It is of type bigint and can not contain NULL.
A Query shows that there is no single row that contains NULL in any column.
Latest findings:
I queried a different table where the search column and the result column happen to have the same datatype. It works, so syntax, passing of parameter, prepare etc. seems to work in principal.
The System.NotImplementedException in the DataTypeName property of the parameter occurs as well but it works anyway.
I rebuilt the index of the table in question. No change.
Still: when I copy/paste the CommandText and execute it in PGAdmin it shows the correct result.
Modifying the Command and using plain text there without parameter and without prepare still does yield nothing. The plain text CommandText was copy/pasted from PGAdmin where it was successfully executed before.
Very strange.
Reverting search column and result column also gives nothing as a result.
Please try these two alternatives and post back your results:
' Alternative 1: fetch the entire row, see what's returned
Dim dr = find.ExecuteReader()
While (dr.Read())
Console.Write("{0}\t{1} \n", dr[0], dr[1])
End While
' Alternative 2: Check if "ExecuteScalar()" returns something other than an int
Dim result = find.ExecuteScalar()
... and (I just noticed Honeyboy Wilson's response!) ...
Fix your syntax:
' Try this first: remove the single quotes around "#code"!
Dim find = New NpgsqlCommand("SELECT serial from dbo.foreigncode WHERE code = #code;", conn)
Update 1
Please try this:
Dim find = New NpgsqlCommand("SELECT * from dbo.foreigncode;", conn)
Q: Does this return anything?
Dim dr = find.ExecuteReader()
While (dr.Read())
Console.Write("{0}\t{1} \n", dr[0], dr[1])
End While
Q: Does this?
Dim result = find.ExecuteScalar()
Q: Do you happen to have a column named "serial"? What is it's data type? Is it non-null for the row(s) with 'XYZ'?
Please update your original post with this information.
Update 2
You seem to be doing ":everything right":
You've confirmed that you can connect,
You've confirmed that non-query updates to the same table work (with npgsql),
You've confirmed that the SQL queries themselves are valid (by copying/pasting the same SQL into PGAdmin and getting valid results).
As Shay Rojansky said, "System.NotImplementedException in the DataTypeName property" is a known issue stepping through the debugger. It has nothing to do with your problem: https://github.com/npgsql/npgsql/issues/2520
SUGGESTIONS (I'm grasping at straws)::
Double-check "permissions" on your database and your table.
Consider installing a different version of npgsql.
Be sure your code is detecting any/all error returns and exceptions (it sounds like you're probably already doing this, but it never hurts to ask)
... and ...
Enable verbose logging, both client- and server-side:
https://www.npgsql.org/doc/logging.html
https://www.postgresql.org/docs/9.0/runtime-config-logging.html
... Finally ...
Q: Can you make ANY query, from ANY table, using ANY query method (ExecuteReader(), ExecuteScalar(), ... ANYTHING) from your npgsql/.Net client AT ALL?
I finally found it. It's often the small things that can have a big impact.
When the value was assigned to the parameter a substring index was incorect.
Now it works perfectly.
Thanks to everybody who spent his time on this.

F#: Cannot call stored procedure on MariaDB database using SQLProvider

I adapted my code from the instructions here.
open FSharp.Data.Sql
let [<Literal>] connection_str = "Server=localhost;Port=3306;SSL Mode=None;Uid=<UID>;Pwd=<PWD>;Database=<DB>"
type provider = SqlDataProvider<Common.DatabaseProviderTypes.MYSQL, connection_str>
let context = provider.GetDataContext()
context.Procedures.SpGetFrontContracts.Invoke(1)
Intellisense works until the period after SpGetFrontContracts. After that, nothing. Trying to compile, I get:
Error FS0039 The field, constructor or member 'Invoke' is not defined.
I am otherwise able to connect to the database and insert and query data, as long as I stick to tables and views.
SpGetFrontContracts is a valid stored procedure in my database (its actual name is sp_get_front_contracts, but the type provider seems to remove underscores). I can run it successfully using HeidiSQL. In case it's useful, here's the create code:
CREATE DEFINER=`<UID>`#`localhost` PROCEDURE `sp_get_front_contracts`(
IN `Group` INT
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
SELECT p.DateTime, p.Contract, p.Volume, c.Name
FROM tbl_contract_price_data p
INNER JOIN tbl_contracts c on p.Contract = c.ID
WHERE c.`Group` = `Group`
ORDER BY p.DateTime
LIMIT 1000;
END
I tried creating a simpler sproc that was named 'test', took no parameters, and simply ran a select statement. It showed up in the type provider under Procedures, but again I could not call Invoke on it.
My best guess is that Invoke is being inherited from some namespace or assembly reference I don't have, so I'm currently looking through the SqlProvider source to try to figure out what it might be. I'm currently referencing:
FSharp.Core
FSharp.Data
FSharp.Data.SqlProvider
mscorlib
System
System.Core
System.Data
System.Numerics
System.ValueTyple
System.Xml.Linq
Thank you for any suggestions.
Edit: It looks like the action is in SqlDesignTime.fs in a function called generateSprocMethod that starts on line 346. I'll try to figure out what's going on in there.
Edit: After three days banging my head against this, I gave up and just used MySQL Connector/NET.
I'm not sure about your underlying data or structures, but I know these are two other (correct) ways to solve it:
WHERE c.`Group` = `Group` -- what you have.
-- possible corrections:
WHERE c.`Group` = p.`Group` -- did you mean this?
WHERE c.`Group` = "Group" -- or this?

Entity Framework ExecuteStoreCommand gives {"ORA-00936: missing expression"}

I'm trying to run the following in a VB.NET application using Entity Framework 6 on an Oracle database:
mrstage.ExecuteStoreCommand("DELETE FROM CB_LISTINGS WHERE ELIGIBLE={0}", eligible)
When it executes, I get the error: {"ORA-00936: missing expression"}
On my table, ELIGIBLE is of type VARCHAR2, and the eligible variable is a string.
If I hardcode the parameter, for example:
mrstage.ExecuteStoreCommand("DELETE FROM CB_LISTINGS WHERE ELIGIBLE='ECB'")
It works fine.
I'd be very grateful if someone can offer any suggestions.
Thanks!
James
In Oracle parameters are named differently, use a column parameter like :0 instead of {0}.
So your code is now:
mrstage.ExecuteStoreCommand(
"DELETE FROM CB_LISTINGS WHERE ELIGIBLE=:0",
eligible)

How to set an SQL parameters in Apps Scripts and BigQuery

I am trying to avoid a sql injection. This topic has been dealt with in Java (How to prevent query injection on Google Big Query) and Php.
How is this accomplished in App Scripts? I did not find how to add a parameter to a SQL statement. Here is what I had hoped to do:
var sql = 'SELECT [row],etext,ftext FROM [hcd.hdctext] WHERE (REGEXP_MATCH(etext, esearch = ?) AND REGEXP_MATCH(ftext, fsearch = ?));';
var queryResults;
var resource = {
query: sql,
timeoutMs: 1000,
esearch='r"[^a-zA-z]comfortable"',
fsearch='r"[a-z,A-z]confortable"'
};
queryResults = BigQuery.Jobs.query(resource,projectNumber);
And then have esearch and fsearch filled in with the values (which could be set elsewhere).
That does not work, according to the doc.
Any suggestions on how to get a parameter in an SQL query? (I could not find a setString function...)
Thanks!
Unfortunately, BigQuery doesn't support this type of parameter substitution. It is on our list of features to consider, and I'll bump the priority since it seems like this is a common request.
The only suggestion that I can make in the mean time is that if you are building query strings by hand, you will need to make sure you escape them carefully (which is a non-trivial operation).

Endeca UrlENEQuery java API search

I'm currently trying to create an Endeca query using the Java API for a URLENEQuery. The current query is:
collection()/record[CONTACT_ID = "xxxxx" and SALES_OFFICE = "yyyy"]
I need it to be:
collection()/record[(CONTACT_ID = "xxxxx" or CONTACT_ID = "zzzzz") and
SALES_OFFICE = "yyyy"]
Currently this is being done with an ERecSearchList with CONTACT_ID and the string I'm trying to match in an ERecSearch object, but I'm having difficulty figuring out how to get the UrlENEQuery to generate the or in the correct fashion as I have above. Does anyone know how I can do this?
One of us is confused on multiple levels:
Let me try to explain why I am confused:
If Contact_ID and Sales_Office are different dimensions, where Contact_ID is a multi-or dimension, then you don't need to use EQL (the xpath like language) to do anything. Just select the appropriate dimension values and your navigation state will reflect the query you are trying to build with XPATH. IE CONTACT_IDs "ORed together" with SALES_OFFICE "ANDed".
If you do have to use EQL, then the only way to modify it (provided that you have to modify it from the returned results) is via string manipulation.
ERecSearchList gives you ability to use "Search Within" functionality which functions completely different from the EQL filtering, though you can achieve similar results by using tricks like searching only specified field (which would be separate from the generic search interface") I am still not sure what's the connection between ERecSearchList and the EQL expression above?
Having expressed my confusion, I think what you need to do is to use String manipulation to dynamically build the EQL expression and add it to the Query.
A code example of what you are doing would be extremely helpful as well.