npgsql executescalar() allways returns nothing - vb.net

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.

Related

Lotus Notes Script

I need to have a script which can copy the value from InternetAddress Field in the person document one by one in names.nsf and append it in the User Name field. Can someone help with a working script?
This can literally be done with a one-line formula, using a simple assignment statement and the list append operator. It is really the most basic thing you can do in all of Lotus Notes programming. It doesn't even need to use any of the #functions.
The syntax for an assignment is:
FIELD fieldThatYouWantToSet := value;
The syntax for the list append operator is:
value1 : value2;
The only other thing you need to know is that value1 and value2 can simply be the names of existing items (a.k.a. fields), and the list of values in the second item will be appended to the list of values in the first item.
Then, all you will need to do is to put this one-liner into a formula agent that runs against all documents in the current view, and run the agent from the Actions menu while you are in the view.
Option-1:
There are a few ways to accomplish this, the simplest being , as the user specified before, a simple field function would do.
FIELD UserName := UserNAme:InternetAddress;
You could set and run the above field function in an agent in $UsersView
In option-2, you could also use the "UnProcessedDoc" feature and set and run as an agent.
But, here, I have written one another way to set and run as an agent in $UsersView.
Hope this helps, please approve this answer if this had helped anyone.
Option:2
At present , no Domino in my System, in order to test this snippet. I wish there exists any method online to test this snippet before I post.
But, logically, consider this snippet as a pseudo-code to accomplish ur objective.
Above all, it has been more than a decade or two ever since I have programmed in Domino. Because, I moved on to RDMS, DW, BI and now to Cloud... well Cloud-9. :)
Here is a portion of lotus script code to copy the value from InternetAddress Field in the person document one by one in names.nsf and append it in the UserName field.
Dim db As New NotesDatabase( "Names Db", "names.nsf" )
Dim view As NotesView
Dim doc As NotesDocument
Dim InternetAddress_value As Variant
Set view = db.GetView( "$Users" )
// loop thru all docs in $Users view.
// Get InternetAddress_value and rep it in UserName
Set doc = view.GetFirstDocument
If doc.HasItem("InternetAddress") Then
While Not(doc Is Nothing)
// in this line we concatenate username with IAaddress_value
new_value= doc.GetItemValue( "username" ) + doc.GetItemValue( "InternetAddress" )
Call doc.ReplaceItemValue( "UserName", new_value)
Call doc.Save( False, True )
Set doc = view.GetNextDocument(doc)
Wend
End If
This solution is posted by Mangai#Notes#Domino#Now_HCL . Encourage to post more solutions by approving the answer.

Return multiple records from subroutine and parse into datatable [Unidata][U2.NET]

I am working with Unidata, and ADO.NET using the U2 .NET Provider. This may be a shot in the dark as there are not many resources for Unidata and .NET these days.
Currently I can only return a single MV record 153926þIþ and parse it using MV_To_DataTable. I'd like to return multiple records like 153926þIþÿ153926þIþÿ. Is there any built in mechanism for doing this? I fear I will have to write the extension to best accomodate me.
I retrieve a single record in a unidata subroutine this way:
SUBROUTINE GETITEMS(results)
EXECUTESQL "SELECT ID, STATUS, DESC FROM ITEMS TO GETITEM_LIST;"
DONE = 0
RECCNT = 0
LOOP
RECCNT += 1
READNEXTTUPLE REC FROM "GETITEM_LIST" ELSE DONE = 1
results := REC
IF RECCNT EQ 1 THEN EXIT
UNTIL DONE
REPEAT
results
CLEARSQL
RETURN
Simple subroutine that returns one record without any record marks. This works when I use the U2Parameter method called MV_To_DataTable to parse it into an existing datatable.
However when I change the subroutine line:
results:= REC to results:= REC : #RM to append the record marks and remove the limit of 1, the MV_To_DataTable no longer is able to parse it correctly. In fact it will throw System.IndexOutOfRangeException: Cannot find column 3.
VB.NET Code:
' ... Open database connection called U2Connection ...
Dim cmd = U2Connection.CreateCommand
cmd.CommandText = "CALL GETITEMS(?)"
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Clear()
cmd.Parameters.Add(New U2Parameter("#arg1", "") With {.Direction = ParameterDirection.InputOutput})
cmd.ExecuteNonQuery()
Dim tb As New DataTable
tb.Columns.Add("ID")
tb.Columns.Add("STATUS")
tb.Columns.Add("DESC")
cmd.Parameters.Item(0).MV_To_DataTable(tb) ' Error happens here
' System.IndexOutOfRangeException: Cannot find column 3.
It appears the method does not separate records. I could be interpretting this incorrectly.
*****UPDATE 2/9/2019
I went ahead and wrote my own extension method to support my return format with the record markers. It populates a datatable with records allowing me to continue as I normally would.
You are kind of straddling the Multivalue/System.Data divide here. If you have not already done so, I would suggest looking into the U2 Toolkit for .NET, which I believe is generally readily available if you are current on maintenance. It comes with some samples of how to do things like this in C# and VB as well some Entity Framework stuff.
But as to what is going on here, You are trying to put a U2Type.DynArray into a System.DataTable is kind of tricky as the DynArray is a Record state, which could contain multiple rows from multiple tables within a DataSet. As #RM is the terminator for a record so it turns DynArray into DynArray[] and you can't have that as a parameter as such.
To fix this with the minimum refactoring, you can still use MV_To_DataTable, but note that it is expecting your data to be tabular and in in a single record. These example assume a newline is an Attribute mark (#FM/#AM)
Here is the contents of what you are returning
Row1Column1
Row1Column2
Row1Column3:#RM
Row2Column1
Row2Column2
Row2Column3:#RM
Row13olumn1
Row13olumn2
Row13olumn3:#RM
And here is what MV_To_DataTable expects
Row1Column1:#VM:Row1Column2:#VM:Row1Column3
Row2Column1:#VM:Row2Column2:#VM:Row2Column3
Row3Column1:#VM:Row3Column2:#VM:Row3Column3
If you adjust your U2 sub to output that, it should work.
Additionally, you could try using your SQL command directly for .net, but that becomes perilous for other reasons depending on your data.
Good Luck!

Baffled by nil results in ruby-dbi Oracle query

I've not played with Ruby in a while, and was just writing a simple db query tool.
The tool connects fine and returns the correct number of results for the query (56 rows in this case), but the value returned for each element is 'nil'. Executing the query in sqlplus works fine.
I've found similar problems on StackExchange, but most of the solutions don't apply, or require using ODBC directly. Ugh.
I'm including a stripped down version of what I've written. Any ideas what I'm doing wrong?
require 'dbi'
dbh = DBI.connect('DBI:OCI8:foodb', 'user', 'password')
rs = dbh.prepare('select field_name from foo_user.cdr_fields where layout like ?')
rs.execute('phi_outage')
while rsRow = rs.fetch do
p rsRow
end
rs.finish
dbh.disconnect
The fetch method is an iterator so no need for a while loop. Try
rs.fetch do|row|
p row unless p.nil?
end
The API states that the method gets called for all remaining rows and will return nil when done.

VB.Net Sqlite - Parameterized query not working

I never asked any questions on stackoverflow but it already brought me tons of answers !
But this time, after some extended research, I have to ask it myself.
I'm using VB.Net with Sqlite and my query doesn't return any value when I execute it with parameters. I guess this has something to do with the fact SituationString contains commas but I really can't figure it out.
Here's is my code :
dim ChildCtx as Integer
dim SituationString as String
SituationString="968,970,978,979,980,981,995,1022,1099,1119"
With DataBase
.SQL_CMD.Parameters.Clear()
.SQL_CMD.CommandText = "SELECT SERVCTX_NO FROM SERVCTX WHERE SERVCTX_NO IN (#situationstring) AND MASTER = '1'"
.SQL_CMD.Parameters.Add("#situationstring", SqlDbType.VarChar, 255).Value = SituationString
ChildCtx = .SQL_CMD.ExecuteScalar
.SQL_CMD.Parameters.Clear()
End with
Connection is open and query works out fine if I write the whole query into one string.
Thanks,
You are mixing two techincs: merging constant data into SQL command and using parameters to pass data.
I suppose SituationString is a list of integer you expect for SERVCTX_NO.
So, you must merge it into statement:
.SQL_CMD.CommandText = "SELECT SERVCTX_NO FROM SERVCTX WHERE SERVCTX_NO IN ("+SituationString+") AND MASTER = '1'"
ChildCtx = .SQL_CMD.ExecuteScalar
Using parameters, as you did, SERVCTX_NO would be expected to be a string with 968,970,978,979,980,981,995,1022,1099,1119 exact content!

Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints. error in VB.Net

There were three similar questions in StackOverFlow but none gave an answer..
If have found why this error in occurring but don't know the fix.
I am using Strongly Typed Dataset for my project which is created as a dll for DAL.
I have added the Sql Server Table into this dataset using the designer and has created a DataAdapter
It works fine when i insert using DataTableAdapter
daLabTest.Insert(txtLabTestId.Text, cmbLabTestType.Text, cmbTestName.Text, txtLabFees.Text, dtpLabEffDate.Value)
but when i want to show the data from the table in a combobox or gridview i get this error.
i told that i found out what the problem is, I just previewed the data using DataSet designer and found out that the Function returns data like this...
The query i wrote to view this in dataset is
Select distinct(TestType) from LabTestTypes
so this should return only one column but the dataset is returning 5 columns but others as null, and the TestName column is a primary which should not be null when returned, so the problem exists..
To resolve this i tried to change the NullValue & AllowDBNull property to [Empty] and true respectively but that didn't worked for me.
Please help me in this...
That overly general constraint exception is nasty, where's the InnerException after so many complaints?!
This template may help identify the problem row and column but a "Fill" version of the query function is needed. E.g. GetDistinct*() --> Fill*(). Then a table can be created and interrogated for the row's error text.
SomeTable tTable = new SomeTable()
try {
// sorry, if you have a GetData, change to the fill version
someTable.FillByActiveLogin(tTable, loginName);
} catch (System.Data.ConstraintException constrExc) {
System.Data.DataRow[] rowsErr = tTable.GetErrors();
for (int i = 0; i < rowsErr.Count(); i++)
if (rowsErr[i].HasErrors)
Dbg.WriteLine(rowsErr[i].RowError);
}
(Thanks Michael S for this hint whoever/wherever you are!)
I got this error in a function from a DLL that uses a stored procedure. The procedure did not return all the fields in the table. One of the fields excluded was one that cannot be null. That apparently caused the constraint exception. When I changed the procedure and the DLL to include that field, the exception went away.
After spending ages on this problem myself, I have resolved it modifying the query in the dataset to return a dummy value (that can be ignored) for each key field that is not required in the output.
So your query would become...
Select distinct TestType, 1 as ID, "Dummy" as TestName, "Dummy" as TestFees, "Dummy" as TestDate
from LabTestTypes