I want to upgrade my web server to newest Ubuntu version and hence also upgrade php5 to php7. I completed the installation and configuration of a VM running lubuntu 16.04 to test things, to see if code changes are needed and also test if it works in general.
In the first application I face a strange issue with oracle (oci8). The application uses server-side paging and also displays stuff like "Total Records" and "Total records (filtered)". Of course these "metrics" are based on simple count queries and they work and display the correct result. However the select statement to get the actually data returns 0 hits. Especially puzzling because it uses the exact same query:
$sQueryInner = "SELECT id, ROW_NUMBER() OVER ($sOrderByClause) R
FROM my_table " . $sWhereClause;
$sQueryFinal = "SELECT id FROM
(" . $sQueryInner . ")
WHERE R BETWEEN :startIndex and :endIndex";
// Total data set length after applying where
$sQueryFilteredCount = "SELECT COUNT(*) as \"totalRowsCount\" FROM (" . $sQueryInner . ")";
Only difference is the ROW_NUMBER() clause but I don't see how that affects things that no results are returned. I also get no error messages or php warnings. oci_fetch_array immediately returns false meaning no further rows found.
while ($row = oci_fetch_array($statementFinal, OCI_ASSOC + OCI_RETURN_NULLS)) {//...
I wanted to find a way to debug oci8 itself. To see the actual SQL sent. But oci_internal_debug seems to be disabled since php5.6.
So I'm pretty lost. Any ideas what could cause this and how I could further debug/search for why it is caused?
EDIT:
Wit wireshark I can actually see the SQL sent to the DB and it's correct. Problem is no rows are returned. Only conclusion is that parameter binding doesn't work properly and hence no results are returned. I don't get it however as the exact same thing works on ubuntu 14.04. Only difference is php7. All other applications also work so the issue is with this specific query. It has a subselect and Row_number() function.
This is another WTF of php. Def. considering rewrite in other language...Seriously php guys, get a grip...
They changed something fundamental which impacts oci_bind_by_name but don't mentioned it anywhere.
The issue can be fixed by reordering your code. Meaning you have to do it in this order if you bind your statements in a function call:
Create Statements
Bind Statement 1
execute statement 1
Bind Statement 2
execute statement 2
and so forth. If you first bind all statements and then execute it, a later call to bind will overwrite previous value even if the parameter has a completely different name and type. WTF?
Related
We are using the new DataStream feature introduced in NetScaler 9 (we're on v10) to do content switching (described here: http://support.citrix.com/proddocs/topic/netscaler/ns-dbproxy-wrapper-con.html). We have a read-only virtual server that balances across several read-only MySql slaves. We use our Content Switching to send all "Selects" over to the read-only server.
the policy is configured as such:
mysql.req.query.command.contains("select")
our users send multi-part queries to our database server. Most often they are simple, like:
use database;
select col1 from table1;
Sometimes they will put comments at the head of the query. for example:
-- this is my query
select col1 from table1;
What we've found is that if the query simply starts with a select, everything works swimmingly. However, in the cases where there is a use statement or comments preceding the query, the content swticher fails to detect that this is a select query and it bypasses our read-only virtual server.
I am about to tell all of our developers that they must fully alias every table in every query and avoid use statements (yes, this is a good thing anyway), and also that they cannot use comments in their sql (that's just silly).
Does anyone know how I can configure my NetScaler DataStream Content Switching to ignore comments and use statements?
The decision on where to send the query is done on the first line received after successful authentication... so ignoring the comment won't work.
You could setup a responder policy which sends back an error message saying "Please don't use SQL Comments in commands sent to the Load Balanced VIP". A bit draconian, but your devs would get the message fairly quick.. but there's no way to ignore the comment, but still base a decision on the select statement. However, I was under the impression that the select statement is up to the first semi colon... so in your example above, it should (in theory) still find the select statement. I'd need to test that to be certain of the behaviour however.
Also - the USE statement is critical. This is the DB on which all subsequent commands are issued.
It would be best practice to NOT use the USE statement, but instead, change the select statement to:
select col1 from database.table1;
Once the USE statement is seen, it prevents any subsequent commands being pipelined down the same connection... So if there are a lot of Use statements, you will not get to enjoy the connection multiplexing functionality that comes with DataStream.
We learned that Block Level comments are acceptable, but single line comments are not.
This is properly ignored:
/* my comment */
These comment styles are treated as part of the query:
-- my comment
# my comment
kind of ridiculous when having SET autocommit=0 is perfectly reasonable. What about in that situation.
Issue with Delphi legacy code. Added one line of code to correct one error and created a new error.
New error is causing the same executable to yield different results on different servers(switched the pointer from dev to prod environment on the executable).
code:
sEscapedString:=stringreplace(sStringIn,'[','''+char(27)+''[',[rfReplaceAll]);
sEscapedString:=stringreplace(sEscapedString,']','''+char(27)+'']',[rfReplaceAll]);
sEscapedString:=stringreplace(sEscapedString,'''','''''',[rfReplaceAll]);// this line created new
bug
result:=' like ''' + Trim(sEscapedString) + '%'''+' escape char(27) ';
When running the code against dev this query finds objects with the characters '[' and ']' in it
Against prod the query does not find those items:
The first thing I checked was the data: Exactly identical in both cases
The second thing I checked was SQL server versions (11.0.3128 on BOTH servers)
The third thing I am checking is settings on those servers:
DBCC USEROPTIONS; -- same on both
SELECT name, collation_Name FROM sys.databases -- same on both
select ##OPTIONS -- same on both.
Quoted identifiers are 'ON' for both servers
It comes down to the fact that I know one server is treating the escape character (chr(27)) differently than the other but I do knot know why.
Does anyone have a theory(or answer) as to why the 2 similar servers are treating the escape characters differently?
The goal here is getting the prod server to return values with '[' and ']', as setting up my system to work with the legacy code will take a LOT of additional time. I do have a fix for the code
sEscapedString:=stringreplace(sStringIn,'[','[[]',[rfReplaceAll]);
But the faster option would seem to be getting the server to read the values the same.
Update: We found the root cause of the difference and it was more mundane than what we expected, turns out the query we were running was actually executed twice. The second execution was missing the key piece on the production server.
The issue was resolved by moving the new line of code so that it executed first rather than last.
I would first try to find out if this SQL only causes different behaviour when it is sent from the application: by sending the SQL from an interactive SQL client tool to both servers.
To make sure that the manually tested SQL is exactly the same as in the application, I would try to log or capture the exact SQL as sent from the application as a text file and then paste its content to the SQL client tool.
If the server is the culprit, then using the SQL from a different client tool should cause the same difference with the two servers. If the client tool shows the same (correct) result on both servers, then something is going on in the Delphi application.
p.s. upvoted, it is an interesting phenomenon
I have used mysql for some projects and recently I moved to postgresql. In mysql when I alter a table or a field the corresponding query will be displayed in the page. But such a feature was not found in postgresql(kindly excuse me if I'm wrong). Since the query was readily available it was very helpful for me to test something in the local database(without explicitly typing the query), copy the printed query and run it in the server. Now it seems like I've to manually do all the trick. Even though I'm familiar with the query operations,at times it can be pretty time consuming process. Can anybody help me? How can I get the corresponding query to get displayed in postgresql(like in mysql) whenever a change is made to the table?
If you use SELECT * FROM ... there should not be any reason for your output to not include newly added columns, no matter how you get your results - would that be psql in command line, PgAdmin3 or any other IDE.
After you add new columns, it is possible that these changes are still in open transaction in other window or SQL command - be sure to COMMIT such transaction. Note that your changes to data or schema will not be visible to any other database clients until transaction commits.
If your IDE still does not show changes, maybe you need to refresh list of tables or if that option is not available, restart your IDE. If that does not work still, maybe you should use better IDE.
If you have used SELECT field1, field2, ... FROM ... then you must add new fields into your SELECT statement(s) - but this would be true for any other SQL implementation, MySQL included.
You could use the LISTEN / NOTIFY mechanism in PostgreSQL to notify your client on altering the database schema.
I am getting some strange behavior involving database queries that I have never seen before and I'm hoping you can illuminate the issue.
I have a table of data called myTable with some columns; thus far everything involving it has been fine. Now, I've just added a column called subTitle; and II notice that the SELECT * Query that pulls in the data for a given record is not aware of that column (it says the returned query does not have a subTitle column), but if I explicitly name the column (select subTitle) it is. I thought perhaps that the Coldfusion server might be caching the query so I tried to work around with cachedwithin="#CreateTimeSpan(0, 0, 0, 0)#" but no dice.
Consider the below code:
<cfquery name="getSub" datasource="#Application.datasourceName#">
SELECT subTitle
FROM myTable
WHERE RecordID = '674'
</cfquery>
<cfoutput>#getSub.subTitle#</cfoutput>
<cfquery name="getInfo" datasource="#Application.datasourceName#">
SELECT *
FROM myTable
WHERE RecordID = '674'
</cfquery>
<cfoutput>#getInfo.subTitle#</cfoutput>
Keeping in mind that record 674 has the string "test" in it's subTitle column the about of the above is
test
[[CRASH WITH ERROR]]
This doesn't make sense to me unless SQL Server 2008 has somehow cached the SELECT * query with the previous incarnation of the table, but the strange thing is if I run the query right from within SQL Management Studio there are no problems and it shows all columns with the select *
Frankly this one has me baffled; I know I can get around this by explicitly naming all the desired columns in the select query instead of using * (which is best practice anyway), but I want to understand why this is occurring.
I've worked with SQL Server 2005 for many years and never had something like this happen, which leads me to believe it might involve something new in SQL Server 2008; but then again the fact that the query works fine inside of the management studio doesn't jive with that either.
===UPDATE===
Clearing the Template Cache in the CF admin will solve the issue
Yes, ColdFusion caches the <cfquery> SQL string. If the underlying table structure changes, the result might be an exception like you see it.
Work-arounds:
Recommended solutiuons:
If you have the development or enterprise version you can view your query cache in the server moniter and clear only the queries there. (comment from #Dpolehonski, thanks)
Otherwise, click Clear Template Cache Now in the ColdFusion Administrator (under Server Settings/Caching).
This will invalidate all cached CFML-Templates on the server and CF will re-compile them when necessary.
Quick and dirty:
Subtly change the query SQL, for example add a space somewhere. When you are on a development machine it's the quickest way to fix the issue.
This will invalidate the compiled version of this query only and force a re-compile.
(Note that removing the subtle change will trigger the error again since the old query text will remain cached.)
Brute-force:
Re-start the ColdFusion server. Brutal, but effective.
Or the quick and super dirty method:
<cfquery name="getInfo" datasource="#Application.datasourceName#">
SELECT
*, #createUUID()# as starQueryCacheFix
FROM
myTable
WHERE
RecordID = '674'
</cfquery>
Don't leave in production code though... it'll obsolete all of the query caching ColdFusion does. I did say it was super dirty ;)
I'm trying to pull user data from 2 tables, one locally and one on a linked server, but I get the wrong results when querying the remote server.
I've cut my query down to
select * from SQL2.USER.dbo.people where persId = 475785
for testing and found that when I run it I get no results even though I know the person exists.
(persId is an integer, db is SQL Server 2000 and dbo.people is a table by the way)
If I copy/ paste the query and run it on the same server as the database then it works.
It only seems to affect certain user ids as running for example
select * from SQL2.USER.dbo.people where persId = 475784
works fine for the user before the one I want.
Strangely I've found that
select * from SQL2.USER.dbo.people where persId like '475785'
also works but
select * from SQL2.USER.dbo.people where persId > 475784
brings back records with persIds starting at 22519 not 475785 as I'd expect.
Hope that made sense to somebody
Any ideas ?
UPDATE:
Due to internal concerns about doing any changes to the live people table, I've temporarily moved my database so they're both on the same server and so the linked server issue doesn't apply. Once the whole lot is migrated to a separate cluster I'll be able to investigate properly. I'll update the update once this happens and I can work my way through all the suggestions. Thanks for your help.
The fact that LIKE operates is not a major clue: LIKE forces integers to string (so you can say WHERE field LIKE '2%' and you will get all records that start with a 2, even when field is of integer type). Your incorrect comparisons would lead me to think your indexes are corrupt, but you say they work when not used via the link... however, the selected index might be different depending on the use? (I seem to recall an instance when I had duplicate indexes and only one was stale, although that was too long ago to recall the exact cause).
Nevertheless, I would try rebuilding your index using the DBCC DBREINDEX (tablenname) command. If it turns out that doing so fixes your query, you may want to rebuild them all: here is a script for rebuilding them all easily.
Is dbo.people a table or a view? I've seen something similar where the underlying table schema had been changed and dropping and recreating the view fixed the problem, although the fact that the query works if run directly on the linked server does indicate something index based..
Is the linked server using the same collation? Depending on the index used, I could see something like this perhaps happening if the servers were not collation compatible, but the linked server was set up with collation compatible (which tells Sql Server it can run the query on the remote server).
I would check the following:
Check your definition on the linked server, and confirm that SQL2 is the
server you expect it to be
Check and compare the execution plans both from the remote and local servers
Try linking by IP address rather than name, to ensure you have the proper machine
Put the code into a stored procedure on the remote machine, and try calling that instead
Sounds like a bug to me - I;ve read of some issues along these lines, btu can't remember specifically what. What version of SQL Server are you running?
select * from SQL2.USER.dbo.people where persId = 475785
for a PersID which fails how does:
SELECT *
FROM OpenQuery(SQL2, 'SELECT * FROM USER.dbo.people WHERE persId = 475785')
behave?