Why are identical SQL calls behaving differently? - postgresql

I'm working on a web app in Rust. I'm using Tokio Postgres, Rocket and Tera (this may be relevant).
I'm using the following to connect to my DB which doesn't fail in either case.
(sql_cli, connection) = match tokio_postgres::connect("postgresql://postgres:*my_password*#localhost:8127/*AppName*", NoTls).await{
Ok((sql_cli, connection)) => (sql_cli, connection),
Err(e) => return Err(Redirect::to(uri!(error_display(MyError::new("Failed to make SQLClient").details)))),
};
My query is as follows. I keep my queries in a separate file (I'm self taught and find that easier).
let query= sql_cli.query(mycharactersquery::get_characters(user_id).as_str(), &[]).await.unwrap();
The get characters is as follows. It takes a user ID and should return the characters that they have made in the past.
pub fn get_characters(user_id: i16) -> String {
format!("SELECT * FROM player_characters WHERE user_id = {} ORDER BY char_id ASC;", user_id)
}
In my main file, I have one GET which is /mycharacters/<user_id> which works. This GET returns an HTML file. I have another GET which is /<user_id> which returns a Tera template. The first works fine and loads the characters, the second doesn't: it just loads indefinitely. I initially thought this was to do my lack of familiarity with Tera.
After some troubleshooting, I put some printouts in my code, the one before and after the SQL call work in /mycharacters/<user_id>, but only the one before writes to the terminal in /<user_id>. This makes me think that Tera isn't the issue as it isn't making it past the SQL call.
I've found exactly where it is going wrong, but I don't know why as it isn't giving an error.
Could someone please let me know if there is something obvious that I am missing or provide some assistance?
P.S. The database only has 3 columns, so an actual timeout isn't the cause.
I expected both of these SQL calls to function as I am connected to my database properly and the call is copied from the working call.

Related

operator does not exist: # timestamp without time zone

In a parameterized query issued from c# code to PostgreSQL 10.14 via dotConnect 7.7.832 .NET connector, I select either a parameter value or the local timestamp, if the parameter is NULL:
using (var cmd = new PgSqlCommand("select COALESCE(#eventTime, LOCALTIMESTAMP)", connection)
When executed, this statement throws the error in subject. If I comment out the corresponding parameter
cmd.Parameters.Add("#eventTime", PgSqlType.TimeStamp).Value = DateTime.Now;
and hardcode
using (var cmd = new PgSqlCommand("select COALESCE('11/6/2020 2:36:58 PM', LOCALTIMESTAMP)", connection)
or if I cast the parameter
using (var cmd = new PgSqlCommand("select COALESCE(cast(#eventTime as timestamp without time zone), LOCALTIMESTAMP)", connection)
then it works. Can anyone explain what # operator in the error is referring to and why the error?
In the case that doesn't work, your .Net connection library seems to be passing an SQL command containing a literal # to the database, rather than substituting it. The database assumes you are trying to use # as a user defined operator, as it doesn't know what else it could possibly be. But no such operator has been defined.
Why is it doing that? I have no idea. That is a question about your .Net connection library, not about PostgreSQL itself, so you might want to add tag.
The error message you get from the database should include the text of the query it received (as opposed to the text you think it was sent) and it is often useful to see that in situations like this. If that text is not present in the client's error message (some connection libraries do not faithfully pass this info along) you should be able to pull it directly from the PostgreSQL server's log file.

unable to set db using string while coding in python

I would like to know if there is a way to set db using a variable
For example: I am coding in Python, and I connect using client = MongoClient(uri). All goes fine.
There are 4 dbs: test1,test2,test3,test4.
I am able to list them all.
dblist = client.list_database_names()
print(dblist)
All goes fine.
Now, Instead of connecting/ using
db = client.test1
Is there a way to use a string rather than actual name of the db?
such as str = 'test1', and then db=client.str.
(this doesn't work)
In my program , I display the list of dbs first and then I am taking user input on the db , and proceed with further flow, but unable to do so.
Please help.
You cannot add string as an name when it comes to that. However there is another function that takes string of the name of certain database and gets the database.
db=client.get_database('test')
Here is the documentation: https://api.mongodb.com/python/current/api/pymongo/mongo_client.html

Microsoft Access DoCmd.OutputTo not recognizing acOutPutQuery

Right now, I am just working with powershell, but I plan on porting this concept to JScript and using the .NET jsc with ActiveXObject('Access.Application'). I have opened my query using $accessapp.DoCmd.OpenQuery("MyQuery") and I can see that it is loaded using $accessapp.CurrentData.AllQueries("MyQuery"). I would like to use $accessapp.DoCmd.OutputTo(acOutputQuery, "MyQuery",<acFormat>, <file>), but for some reason, I keep getting the error:
Unexpected token 'acOutputQuery' in expression or statement
Just running $accessapp.DoCmd.OutputTo shows that is what is expected:
void OutputTo (AcOutputObjectType, Variant, Variant, Variant, Variant, Variant, Variant, AcExportQuality)
Every resource I have seen, including the Microsoft OutputTo documentation uses the acOutputObjectType in this manner, so I am completely stumped.
Okay, sorry it took me a while to get back. Thanks to #HansUp for leading me down the correct path. I Used the AcOutputObjectType enumeration link he posted as well as the MS Constants Enumeration. I'll give both a powershell example and an MS JScript one. I'll use acOutputQuery and xcFormatTXT as 1 and "MS-DOS" respectively here, but there are many others in the two links above.
powershell:
$acc = New-Object -com Access.Application
$acc.OpenCurrentDatabase("<path_to_file>.accdb")
$acc.DoCmd.OpenQuery("MyQuery")
$acc.DoCmd.OutputTo(1,"MyQuery","MS-DOS", "<path_to_output_file>.txt")
MS JScript:
function writeToTextFile(dbPath,queryName,outputPath){
var acc = new ActiveXObject("Access.Application"); //create new COM instance
acc.OpenCurrentDatabase(dbPath+".accdb"); //open the database
if(!acc.CurrentData.AllQueries(queryName).IsLoaded){
acc.DoCmd.OpenQuery(queryName); //load the query if it is not loaded yet
}
acc.DoCmd.OutputTo(1,queryName,"MS-DOS",outputPath+".txt"); //write to file
}
These two are kind of quick and dirty. Since I have this working in JScript now, I will probably make a writeToFile() function that takes the format as an argument. I considered using an object to map the name string to the enumeration, but I don't know how useful that would actually be. I suppose if you wanted, you could take the output object as an argument, too, but I only plan to use query objects for now.

Preparing a command with Structured Parameters

I have this ADO.NET command object and I can set some parameters and execute it successfully.
_mergecommand.Parameters.Add(new SqlParameter("values", SqlDbType.Structured));
_mergecommand.Parameters["values"].TypeName = "strlist";
_mergecommand.Parameters["values"].Direction = ParameterDirection.Input;
_mergecommand.Parameters["values"].Value = valuelist;
_mergecommand.ExecuteNonQuery();
This works fine. But I want to prepare this command before executing it because I need to run this millions of times. I am using SQL Server 2008. I get this error if I try to prepare it
SqlCommand.Prepare method requires all variable length parameters to have an explicitly set non-zero Size.
Any idea how to do this?
This is old, but there does appear to be a correct answer which is to use -1 as the size, e.g.:
_mergecommand.Parameters.Add(new SqlParameter("values", SqlDbType.Structured, -1));
If you have to do it millions of times using a command like this is probably not a good strategy.
Can you serialize your data into an XML string and pass that as a single argument? That will be considerably less load on your network and SQL Server.... although it will probably hit your client a lot harder.
If you are dead set on doing it that way, maybe what you are looking for is an overload of the SqlCommand.Parameters.Add method:
_mergecommand.Parameters.Add("#values", System.Data.SqlDbType.NVarChar, 100).Value = foo;
is that more like what you wanted?

After querying DB I can't print data as well as text anymore to browser

I'm in a web scripting class, and honestly and unfortunately, it has come second to my networking and design and analysis classes. Because of this I find I encounter problems that may be mundane but can't find the solution to it easily.
I am writing a CGI form that is supposed to work with a MySQL DB. I can insert and delete into the DB just fine. My problem comes when querying the DB.
My code compiles fine and I don't get errors when trying to "display" the info in the DB through the browser but the data and text doesn't in fact display. The code in question is here:
print br, 'test';
my $dbh = DBI->connect("DBI:mysql:austinc4", "*******", "*******", {RaiseError => 1} );
my $usersstatement = "select * from users";
my $projstatment = "select * from projects";
# Get the handle
my $userinfo = $dbh->query($usersstatement);
my $projinfo = $dbh->query($projstatement);
# Fetch rows
while (#userrow = $userinfo->fetchrow()) {
print $userrow[0], br;
}
print 'end';
This code is in an if statement that is surrounded by the print header, start_html, form, /form, end_html. I was just trying to debug and find out what was happening and printed the statements test and end. It prints out test but doesn't print out end. It also doesn't print out the data in my DB, which happens to come before I print out end.
What I believe I am doing is:
Connecting to my DB
Forming a string the contains the command/request to the DB
Getting a handle for my query I perform on the DB
Fetching a row from my handle
Printing the first field in the row I fetched from my table
But I don't see why my data wouldn't print out as well as the end text. I looked in DB and it does in fact contain data in the DB and the table that I am trying to get data from.
This one has got me stumped, so I appreciate any help. Thanks again. =)
Solution:
I was using a that wasn't supported by the modules I was including. This leads me to another question. How can I detect errors like this? My program does in fact compile correctly and the webpage doesn't "break". Aside from me double checking that all the methods I do use are valid, do I just see something like text not being displayed and assume that an error like this occurred?
Upon reading the comments, the reason your program is broken is because query() does not execute an SQL query. Therefore you are probably calling an undefined subroutine unless this is a wrapper you have defined elsewhere.
Here is my original posting of helpful hints, which still apply:
I hope you have use CGI, use DBI, etc... and use CGI::Carp and use strict;
Look in /var/log/apache2/access.log or error.log for the bugs
Realize that the first thing a CGI script prints MUST be a valid header or the web server and browser become unhappy and often nothing else displays.
Because of #3 print the header first BEFORE you do anything, especially before you connect to the database where the script may die or print something else because otherwise the errors or other messages will be emitted before the header.
If you still don't see an error go back to #2.
CGIs that use CGI.pm can be run from a command line in a terminal session without going through the webserver. This is also a good way to debug.