SYBASE cursor declare as for read only become infinitive - sybase-ase

There is a simple cursor, which has 260 records. Inside the loop not only print but update some tables. There is not only code, but explanation
/*Declare cursor for read only*/
DECLARE crsr_one CURSOR FOR
SELECT a,b,c,d
FROM table_name
WHERE a>=100
for read only
OPEN crsr_one /*open cursor*/
DECLARE #a,#b,#c,#d /*declare loop variables*/
while (1=1) /*start while loop*/
BEGIN
FETCH crsr_one into #a,#b,#c,#d /*fetch into variable */
IF (##sqlstatus = 2) /*Break if no more records*/
break
/*some other code with select and update table*/
print "%1! %2! %3! %4!", #a,#b,#c,#d /*Print variables*/
END
The problem is:
In the while loop it became infinitive and brings the same data.
Any idea why and how to correct it?

Your code looks good (except that the syntax for the DECLARE is invalid).
If the loop doesn't break on ##sqlstatus = 2, then the obvious question is: what value does it have? It can also be '1', indicating an error. To find out, print the value.
To be fully correct you should therefor also test for ##sqlstatus = 1. The easiest way to do this is to test for ##sqlstatus != 0 which covers both values 1 and 2.

Related

Lock a Select on the Postgres Database and updating the Column of “value+1” when necessary

I am updating this question, please do not mind the comments below as, instead of deleting this question, I reworked it to give it a sense.
A form on a php page let me create a csv file, to name this file I need to run a SELECT on the database, it the name does not exists, my query must create it; if the name exist, it must update it.
The problem is, there is a chance where 2 or more users can push the submit button at the same time.
This will cause the query to reurn the same value to all of them, therefore creating or updating the file in a non-controlled way.
I need to create a system, that will LOCK the table for INSERT/UPDATE and, if in the meantime another connection appear, the column on the database that will name the file must be incremented of +1.
$date = date("Ymd");
$csv = fopen("/tmp/$user_$date_$id_$reference.csv", 'w+');
Where "reference" is a progressive number in the format of "Axxxx". x's are numbers.
The SELECT would be:
$sql = pg_query($conn, " SELECT user, identification, reference, FROM orders WHERE identification = '$_POST[id_order]' ORDER BY date DESC LIMIT 1");
while ($row = pg_fetch_row($sql)) {
$user = $row[0];
$id = $row[1];
$reference = $row[2];
}
I need to create a function, like the one below, where users can both INSERT and UPDATE, and in the case of concurrent connection, the ones that are not the first will have "reference" incremented of 1.
CREATE OR REPLACE FUNCTION upsert_identification( in_identification TEXT, in_user TEXT ) RETURNS void as $$
BEGIN
UPDATE table SET identification=in_identification, user=in_user, reference=in_reference WHERE identification = in_identification;
IF FOUND THEN
RETURN;
END IF;
BEGIN
INSERT INTO table ( identification, user, reference ) VALUES (in_identification, in_user, in_reference );
EXCEPTION WHEN OTHERS THEN
-- Should the increment be here?
END;
RETURN;
END;
$$ language plpgsql;
I hope what I'm asking is clear, re-read and I do understand it. Please comment below for any question you might have.
I really hope someone can help me!
I was looking for some clues in the postgres manual, I found this link about locking but I am not so sure this is what I need: LINK

Why would `mysqli_fetch_assoc` be returning an empty object?

I'm having to debug some legacy PHP code and I've hit a real puzzler.
A method loops through each row of a MySQL table and adds the row to an array.
Unfortunately, the method is returning a completely empty object, so the HTTP response is of zero-length.
It seems that one particular row in the MySQL table is causing this issue, when mysqli_fetch_assoc is called. I've narrowed it down to row 1251 by adding in the test code below.
$counter = 0
while ( $row = mysqli_fetch_assoc($findInfo) ) {
// My Debug Test Code: bail out and return row 1251
if ($counter == 1251)
return $row; // this returns a populated array for all rows except 1251, which is blank
// Add the row to our array
array_push($rowArray, $row);
$counter = $counter + 1
}
// Finally, do something with all the rows
return $rowArray
If I generate a .CSV dump of the data table, the data looks fairly innocuous - row 1251 is the line beginning 94340 in the snippet below:
94339,"Hills Coaches (Wolverhampton)",,,,,,,,,,,,,,,,
94340,"Hinckley Bus",,"via contact form at www.arrivabus.co.uk/contact-arriva/  ","01455 239329",,,"5 Jacknell Road, Dodwells Bridge Industrial Estate, Hinckley LE10 3BS",,,,,,,,,,www.arrivabus.co.uk/hinckleybus/#http://www.arrivabus.co.uk/hinckleybus/#
94341,Hirethisbus.com,,,,,,,,,,,,,,,,
What might cause mysqli_fetch_assoc to apparently 'bail out' in this way and return nothing? How would I even debug this?
The MySQL row contained some unprintable characters, determined by connecting to the server via the MySQL client and running a manual SELECT on the row.
`SELECT ColumnName FROM TableName WHERE Id = SomeID`
======+==========+===========
ColumnName +========+========
=============================
http://some.site.com/??
=============================
The two question marks were the giveaway.
Still no idea why mysqli_fetch_assoc was unhappy with it, though.

Adodb.GetRow() not returning data when there is a Insert before a Select in the query

I'm new. Most of the times I find solutions here just by reading but now I have to ask you directly because of the weirdness of my subject.
I have an application in php and I used to use the mssql libraries to connect to MS Server 2008 but now I migrated part of my code to connect through ADODB http://adodb.sourceforge.net/
I have a store procedure which I use to validate/insert/update/delete rows depending of parameters I send, so at the very bottom I have a line of code like this
Select #Result Result
This variable just tell me everytime if the proccess went correctly or if I'm missing something so the row doesn't get inserted/deleted/updated.
Here the code of my store procedure
create procedure sp_MyTable #id int, #name varchar(100), #type varchar(10)
as
declare #Results varchar(100)
set #Result=#type
--validations!
if exists(select * from MyTable where name=#name)begin
set #Result='No insert:('
end
if #Result='insert'
insert into MyTable (name)values(#name)
select #Result Result
Here and example of code to create my connection in php
$pQry='exec sp_MyTable #id="0",#name="Hello",#type="insert"';
require ("php/ExtClases/adodb5/adodb.inc.php");
$db = ADONewConnection('mssqlnative');
$db->debug = false;
$db->Connect($datCon['sServer'], $datCon['UID'], $datCon['PWD'], $datCon['Database']);
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rs = $db->Execute($pQry);
$rows=$rs->GetRows();
So, it is supposed to return and Array like this
print_r($rows);
//Array ([0]=>Array( [Result] => insert )) )
But It prints just nothing.
Using Management Studio I already ran this procedure directly on my own computer and at the server online and both cases retrieved data, so the store procedure is fine.
If I remove the insert statement:
create procedure sp_MyTable #id int, #name varchar(100), #type varchar(10)
as
declare #Results varchar(100)
set #Result=#type
--validations!
if exists(select * from MyTable where name=#name)begin
set #Result='No insert:('
end
/*
No insert!
*/
select #Result Result
It works!.
print_r($rows);
//Array ([0]=>Array( [Result] => insert)) )
_UPDATE: even if I print something (print 'something') in the store procedure ADODB ignores the select statement, so the select must be totally alone.
I think I will consider searching for another way.
_.
PD: Sorry for my bad english.
Regards.
Well, it took a few hours of my appreciated life but at last now I know what is going on.
MSSQL driver use to ignore all but the last statement (as I remember...). So, if you have something like this
$query="select * from table1; select some, data from table2; select yadda yadda from table3";
$conn=mysql_connect($sServer,$UID,$PWD);
$baseDatos=mysql_select_db($Database,$conn);
$res=mysql_query($query);
While($row=mssql_fetch_array($res)){
print($row);
}
You will have printed the results only of table3.
( ACTUALLY Here it is written that you can have multiple recorset and navigate through them with mssql http://www.php.net/manual/es/function.mssql-next-result.php but at the moment I don't know why it takes just the last one as the first one. Maybe it doesn't recognize prints or inserts as recorsets at all)
ADODB library actually uses SQLSRV to handle connections and queries to any sql server (mssqlnative). SQLSRV is the official driver released for Microsoft so is slightly different. You need to use the function sqlsrv_next_result or it will be return just the first result whatever it is (print,insert,select,etc)
here the link
http://www.php.net/manual/en/function.sqlsrv-next-result.php
and another guy who had the same problem
SQLSRV and multiple selects in Stored Procedure
what I did is not pretty but with patience I think I can fix it in the future, for now I just need the last recorset (table3) and not the first, so ...
/*here my temporary fix*/
do {
$result = array();
while ($row = sqlsrv_fetch_array($this->_queryID)) {
$result[] = $row;
}
} while (!is_null(sqlsrv_next_result($this->_queryID)));
return $result;
/**/
I overwrite the variable $result with every step into the results :). Funny code.
Cheers

Using a SELECT Query to look up a UPDATE Query on MySQL

I'm using a SELECT query to obtain a variable using mysql_fetch_assoc. This then puts the variable into an UPDATE variable to put the returned value back into the database.
If I hard code the value, or use a traditional variable and it goes in just fine, but it doesn't work when using a value previously retrieved from the database. I've tried resetting the array variable to my own text and that works.
$arrgateRetrivalQuery = mysql_query(**Select Query**);
$arrGate = mysql_fetch_assoc($arrgateRetrivalQuery);
$arrivalGateTest = $arrGate['gatetype'];
$setGateAirportSQL = "UPDATE pilots SET currentgate = '".$arrivalGateTest."' WHERE pilotid = '".$pilotid."'";
$setGateAirportQuery = mysql_query($setGateAirportSQL);
// Close MySQL Connection
mysql_close($link);
This will just make the field to update have nothing in it, however whenever I remove the variable from the SELECT to one I define, array or not, it will work.
Hope this is clear enough. Thanks in advance.
Is arrivalGateTest a number or a string? How did you try to put another value in the query? If you are sure the previous query returns a value, try to write: $setGateAirportSQL = "UPDATE pilots SET currentgate = '$arrivalGateTest' WHERE pilotid = '$pilotid'";.
Just change your sql to inlcude a subquery.
You could use the following general syntax:
UPDATE pilots SET currentgate = (SELECT gate FROM airport WHERE flight='NZ1') WHERE pilotid='2';
which is demonstrated on this fiddle
This saves the extra query and more accurately describes what you are trying to achieve.
WARNING - test it carefully first!

Serialize/Unserialize database data?

Is it possible to serialize data posted by a form, and insert it into a database, and then if it needs updating, unserialize it, and just update the data that was changed?
If it is possible, would someone be kind enough to provide/write a small script to do this?
To answer your question directly all you need to do is:
$data = serialize($_POST);
$sql = "INSERT INTO `table` (`data`) VALUES ('".addslashes($data)."')";
...
However I would strongly recommend you don't serialize the data and put it into the database. It'll make the data very difficult to search, update, etc. You'll be forced to rely on your application to maintain the data integrity!
I would suggest designing a database table that fits in with your form's structure... If your form structure is dynamic, then you'll need to create multiple tables in order to store the data.
Yes, you can do this, but it's not clear why you would want/need to. It'd be difficult/impossible to query the serialized data once it's in the database, and to update it you would have to pull the data from the database, unserialize it, update it, serialize it, and update the appropriate row.
You could encode the POSTDATA using JSON and store in database. When you need the data back, just decode the JSON.
Here's a function to extract single string values from serialized data...
Usage would be something like...
SELECT PARSE_PHP_SERIALIZED_DATA_STRING(
`serialized_data`, 'EmailAddress'
)
FROM `your_table`
WHERE `serialized_data` LIKE '%EmailAddress%'
Here's the function:
DELIMITER $$
--
-- Functions
--
DROP FUNCTION IF EXISTS `PARSE_PHP_SERIALIZED_DATA_STRING`$$
CREATE FUNCTION `PARSE_PHP_SERIALIZED_DATA_STRING`(str_data BLOB, str_index VARCHAR(252)) RETURNS varchar(255)
DETERMINISTIC
BEGIN
-- Declare variables must be done at top of BEGIN END
DECLARE start_pos INT;
DECLARE string_out VARCHAR(255);
DECLARE string_search VARCHAR(255);
DECLARE quote_string VARCHAR(6);
-- The indexes in a php serialized string are quoted and end with a semi-colon
-- Setting the quote string incase the "developer" before you (who thought
-- it was a good idea to dump serialized data in to a single column) then also
-- randomly html encoded the string every third row.
SET quote_string = '"';
SET string_search = CONCAT(quote_string, str_index, quote_string, ';');
-- search for the index
SET start_pos = LOCATE(string_search, str_data);
IF start_pos = 0 THEN
-- not found it so lets search again but with html entities
SET quote_string = '"';
SET string_search = CONCAT(quote_string, str_index, quote_string, ';');
SET start_pos = LOCATE(string_search, str_data);
END IF;
-- still not found it, then it is not there as an index
IF start_pos = 0 THEN RETURN '';
END IF;
-- cut up the string to get just the value
-- the offsets here work for string values
-- maybe a different function for integer values??
SET start_pos = start_pos + LENGTH(string_search);
SET string_out = SUBSTRING(str_data, start_pos,255);
IF SUBSTRING(string_out,1,2) = 'N;' THEN
RETURN '';
END IF;
SET string_out = SUBSTRING(string_out, LOCATE(quote_string,string_out)+LENGTH(quote_string), LOCATE(quote_string,string_out,LOCATE(quote_string,string_out)+1));
SET string_out = SUBSTRING(string_out, 1,LOCATE(quote_string,string_out)-1);
RETURN string_out;
END$$
DELIMITER ;

Resources