My current MSSQL table has a "phone" column which is a varchar. Unfortunately, the phone numbers that are already in the database are not in standard format. For example, 888-888-8888 OR 888/888/8888 OR (888)8888888 OR 8888888888.
I want to get all the rows that are equivalent to 88888888, i.e it should match with 888-888-8888, (888)888888 etc.
I have tried using REPLACE() but there are certain rows where entries have other alphabetic characters like "e", "ex", "ext", etc. So I would like to replace all non-numeric characters.
What would be the best way to get the "matching" rows using MSSQL query?
You can try this function (MS SQL Server):
CREATE FUNCTION uf_RemoveNotNumbers (#str varchar(max))
RETURNS varchar(max)
AS
BEGIN
WHILE #str LIKE '%[^0-9]%'
SET #str=replace(#str, substring(#str, patindex('%[^0-9]%',#str),1),'');
RETURN #str
END
GO
DECLARE #str varchar(max);
SET #str = 'q56--89+9*67qweresr';
select dbo.uf_RemoveNotNumbers (#str)
A simple version using MySQL:
SELECT * FROM `phones` WHERE `phone` LIKE '%8%8%8%8%8%8%8%8%8%8%'
Using PHP:
// Get all your table rows into $rows using SELECT ..
foreach ($rows as $row) {
$row['phone'] = preg_replace('/\D/', '', $row['phone'];
// Save the row using UPDATE ..
}
The regular expression \D matches any non-numeric character. See php.net/preg_replace for more information.
If you just want to find a row that matches "8888888888", then you could use:
if (preg_match('/\D*8\D*8\D*8\D*8\D*8\D*8\D*8\D*8\D*8\D*8\D*/', $row['phone'])) {
..
}
Which could simplify/abstract to:
$match = '8888888888';
if (preg_match('/' . preg_replace('/(\d)/', '\D*$1', $match) . '\D*/', $row['phone'])) {
..
}
Why not write a php script that would do it for you?
ex. get all rows -> replace -> update
heres the query that might work on MSSQL.
create FUNCTION dbo.Only_Numbers
(
#string VARCHAR(8000)
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #IncorrectCharLoc SMALLINT
SET #IncorrectCharLoc = PATINDEX('%[^0-9]%', #string)
WHILE #IncorrectCharLoc > 0
BEGIN
SET #string = STUFF(#string, #IncorrectCharLoc, 1, '')
SET #IncorrectCharLoc = PATINDEX('%[^0-9]%', #string)
END
SET #string = #string
Return #string
END
GO
select dbo.Only_Numbers('888*88-88/2')
You can try this code:
$query="select * from tablename";
$result=mysql_query($query);
while($row=mysql_fetch_array($result))
{
$str = preg_replace('[\D]', '', $row['phone']);
}
Related
I have a TXT file with no punctuation between them. I would like to shred this file by the table column widths in the database and save it.
Let me tell you this step by step…
I’m creating a table in the database with my tabloolustur.php page. The column numbers and column widths of the tables I create will not be the same.
There are no punctuation marks between the TXT file data. First, I want to split the TXT file rows by column width.
$result = $baglanti->prepare("SHOW COLUMNS FROM customers where Field NOT IN('id')");
$result->execute();
$colcount = $result->columnCount()-1;
$columLen = array();
foreach($result as $key => $col){
preg_match('/\d+/', $col['Type'], $len);
$len = (isset($len[0]))? $len[0] : '';
$fieldname = $col['Field'];
$columLen[$fieldname] = $len;
}
For this, I get the number of columns and column widths with the code.
Then, I separate the data with commas with the following function.
function txtBol($metin, $genislik){
$parcala=array();
foreach ($genislik as $sutunadi => $lenght)
{
$parcala[$sutunadi] = substr($metin, 0, $lenght);
$metin = substr($metin, $lenght);
}
return $parcala;
}
I also get column names with the following code. (ps: to use in a query)
$KolAdi = $baglanti->query("SHOW COLUMNS FROM customers where Field NOT IN('id')");
$KolAdi->execute();
$colonAdi= $KolAdi->fetchAll(PDO::FETCH_COLUMN);
$colonAdi=implode(',', $colonAdi);
It prints the data i split correctly when printing it to the screen. So far, so good. But I can’t create the right query with PDO. How should I create the query? (ps: Table column names and column widths are not the same. There will be different numbers and width columns for each table)
I would appreciate it if you could help. I proceeded by implementing some solutions from your site.
Table:
id
name
cev1
cev2
cev3
1
MARTIN EDEN
AAAAAA
BBBBB
CCCC
txt:
MARTIN EDEN........AAAAAABBBBBDDDD
Assuming a valid PDO connection in $PDO, you can do the whole job like this.
It reads the column data once and uses that to create a query to prepare and a regular expression to extract the data.
$table = 'customer';
$txtFile = 'cust.txt';
// No need to prepare this since there's no untrusted data here.
$result = $pdo->query("show columns from `$table` where Field <> 'id'");
// Get column names and widths in arrays
while($columns = $result->fetch(PDO::FETCH_ASSOC)) {
$colNames[] = $columns['Field'];
preg_match('/\d+/', $columns['Type'], $len);
$colLengths[] = $len[0]??'';
}
// Create regex to extract data from lines:
// Looks like this: /(.{20})(.{10})(.{5})/
$regex = '/(.{'.implode('})(.{',$colLengths).'})/u';
// Create skeleton query with table name and field names and placeholders
// Looks like this: INSERT customer (name,addr1,postcode) VALUES (?,?,?)
$query = "INSERT $table (`".implode('`,`', $colNames).'`) VALUES ('.str_repeat('?,', count($colNames)-1).'?)';
// Read text file
if ($fileData = file($txtFile)) {
// Prepare the query only once
$stmt = $pdo->prepare($query);
foreach ($fileData as $row) {
// Get the data using the regex from above
preg_match($regex, $row, $rowData);
// Remove the first row of the regex matches - see PHP manual for why
array_shift($rowData);
// Now execute the prepared query using the data extracted by the regex.
$stmt->execute($rowData);
}
}
Note that this codes assumes that the table consists of a series of contiguous columns from which it can extract column widths, and no other columns except id, which it ignores. If your actual table structure is different you'll need to modify the SHOW COLUMNS query to omit those columns, or modify the code that extracts the column data to extract only the relevant columns.
{Edit]
Updated the code to include /u UTF-8 modifier on the regex, and to wrap the column names in the INSERT query in back ticks.
you can create a table like this and you don't need to check a number of fields by rows
let me know if this useful
CREATE TABLE new_table (
id INT NOT NULL AUTO_INCREMENT,
row_id INT NULL DEFAULT 0,
row_field_name VARCHAR(50) NULL DEFAULT NULL COMMENT 'Index of ',
row_value VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (id));
I get an error saying: "Conversion failed when converting the varchar to data type int
"
when I try to run the code below, but I already converted the ASSIGNED_ID to int in php ?
The $row["ID"] number is small its 2 so there are no , or anything like that, I even added a replace code to remove any spaces, but it still doesn't work. Also both tables have the same ID (data type: int)
I would also like to know how I can join the two tables: T_ASSIGNED and T_EQ using their ID (int) they both have it and it always matches
// SEND A SELECT QUERY TO MSSQL
$query = mssql_query('SELECT ID FROM [TestT].[dbo].[T_ASSIGNED] WHERE [A_T_N]=\'$contact_lastname\'');
$row = mssql_fetch_array($query);
if (strlen($row["ID"])<>0) {
// REMOVE ANY SPACES AND CONVERT ID TO INT
$ASSIGNED_ID = intval(str_replace(" ", "", $row["ID"]));
}else{
// IF NO ID IS FOUND MAKE ID BE ZERO
$ASSIGNED_ID =intval('0');
};
// FREE THE QUERY RESULT
mssql_free_result($query);
// ECHO THE ID
ECHO("TEST ID: ".$ASSIGNED_ID);
// GET THE T NUMBER IN THE T_EQ LOCATION
$query = mssql_query('SELECT EQ_T_N FROM [TestT].[dbo].[T_EQ] WHERE [ID]=\'$ASSIGNED_ID\'');
$row = mssql_fetch_array($query);
// ECHO THE EQ_T_N
echo(">".$row["EQ_T_N"]."<");
// FREE THE QUERY RESULT
mssql_free_result($query);
THANKS FOR ANY HELP.
use this
mssql_query('SELECT EQ_T_N FROM [TestT].[dbo].[T_EQ] WHERE [ID]="' . $ASSIGNED_ID .'"');
by using single quotes, you're using the text of $ASSIGNED_ID, not the value of that variable
I have a Postgres database I wish to access. I need to call several functions that exist in the DB. I have achieved connection to the database and running queries. I have also achieved to call the functions I want. My problem is that when a Postgres function has more than one OUT parameters, instead of returning an array I can access either with the offset or with the row name, it instead returns a string with both the OUT parameters:
$query = "Select pg_function('" . Getenv("REMOTE_ADDR") . "')";
$result = pg_query($query);
$line = pg_fetch_array($result, NULL, PGSQL_ASSOC);
var_dump($line);
What var_dumb returns is this:
array
'ua_bl_session_request' => string '(c6787f5f2b2c885168162c8c8ffff220,8fe04393-c188-0e08-b710-a2ce89066768)' (length=71)
I can of course parse that string but is there a way to achieve what I want and I am missing it?
SELECT * FROM pg_function(REMOTE_ADDR);
Maybe you are using pg_fetch_array() incorrectly, because you should give the row number in the second parameter. For example:
// To get the first row (Rows are numbered from 0 upwards)
$line = pg_fetch_array($result, 0, PGSQL_ASSOC);
// To get the second row
$line = pg_fetch_array($result, 1, PGSQL_ASSOC);
But if you know what you are doing, you can use regexp_split_to_table(), it is a Posgtres string function that split a string to rows using a POSIX regular expression as the delimiter. For example:
$query = "select regexp_split_to_table(
pg_function('" . Getenv("REMOTE_ADDR") . "'), ','
)";
In your case, it will split the function's result using ',' as delimiter. It should return a result set with two rows, like below:
c6787f5f2b2c885168162c8c8ffff220
8fe04393-c188-0e08-b710-a2ce89066768
I want to make a product search engine where the user types in a product code and it will bring back the result, this is easy.
But, I want to be able to compensate for numbers that look like letters and vice versa.
E.g a user types 6O12l, but the product code is actually 60121.
What do I need to put in the SQL query to bring back all products with 6O12l and/or 60121?
So far I have this which isn't working, it keeps bringing back the same result everytime no matter what I type in:
$searchString = $_POST['query'] ;
$searchString = preg_replace('#\W#', '', $searchString);
$firstLetter = substr($searchString, 0, 1) ;
include("db.php") ;
$result = $dbh->prepare("SELECT productCode
FROM products
WHERE productCodeREGEXP '6[O0]12[1l]'
AND productCode LIKE '$firstLetter%'") ;
$result->execute() ;
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
echo $row['productCode'].'<br />' ;
}
I have managed to get it working, but I have encountered a new problem.
I'm using str_replace to substitute the letters for numbers and viceversa in the users query string, but it will only work for one or the other, not both:
$qString = str_replace(array('o', 'l', '0', '1'), array('[O0]', '[1l]', '[O0]', '[1l]'), $searchString) ;
Which gives me a mangled output of e.g. A[[1l]l]BC
Instead of A[1l]BC
Do you have product codes with letters? You can translate the query string to all numbers before you run the query. That's the easiest thing to do, and will be much faster than testing for both.
You can't search the database efficiently with regular expressions. However, you can transform your data for storage in a normalised form, and search using a normalised query string e.g. all O's to zeros, I and l's to ones and so on.
Use this:
SELECT * from products
where code REGEXP '6[O0]12[1l]'
I solved it :D
For reference, I found this function on PHP.net:
function search_replace($s,$r,$sql)
{ $e = '/('.implode('|',array_map('preg_quote', $s)).')/';
$r = array_combine($s,$r);
return preg_replace_callback($e, function($v) use ($s,$r) { return $r[$v[1]]; },$sql);
}
Another option
// regex expresssion
// str_replace goes in order, first change letters to numbers, then change to the regex
// 6012ol becomes 6[0O][1l]2[0O][1l]
$regexString = str_replace(array('o', 'l', '0', '1'), array('0', '1', '[0O]', '[1l]'), $searchString);
// like expression, allows the database to make the initial filter, _ is the single character match
// 6012ol becomes 6__2__
$likeString = str_replace(array('o', 'l', '0', '1'), '_'), $searchString);
$filt1 = "(productCode LIKE '$likeString%')"; // last % allows for partial matches
$filt2 = "(productCode REGEXP '$regexString')";
// now query, with the like filter first
$dbh->prepare("SELECT productCode
FROM products
WHERE $filt1 AND $filt2
") ;
Ok, here's an easy one:
I have a table in MySQL where I keep some country names (inserted by the user). The "problem" is that some of the users inserted the country name having no first capital letter.
A need a script (query+PHP) that selects all the values from 1 column inside the table, and apply a PHP script that makes the first letter of every word a capital letter, and the rest in small letter.
Example:
Before edit:
Name oNe
cOUNTRY
VaLue
value
After edit:
Name One
Country
Value
Value
I want to know two things:
->easiest way to edit a value inside a mySQL table
->easiest PHP way to capitalize the first letter of every word (space separated) inside a script
Thanks!
You can use this function:
DELIMITER $$
DROP FUNCTION IF EXISTS `ICap`$$
CREATE FUNCTION `ICap`(mystring varchar(1000))
RETURNS VARCHAR(1000)
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE myc, pc CHAR(1);
DECLARE myoutstring VARCHAR(1000) DEFAULT LOWER(mystring);
WHILE i <= CHAR_LENGTH(mystring) DO
SET myc = SUBSTRING(mystring, i, 1);
SET pc = CASE WHEN i = 1 THEN ' ' ELSE SUBSTRING(mystring, i - 1, 1) END;
IF pc IN (' ', '&', '''', '_', '?', ';', ':', '!', ',', '-', '/', '(', '.') THEN
SET myoutstring = INSERT(myoutstring, i, 1, UPPER(myc));
END IF;
SET i = i + 1;
END WHILE;
RETURN myoutstring;
END$$
DELIMITER ;
After that, you can retrieve results like this:
SELECT
ICap(name)
FROM
MyTable
or just update all the rows:
UPDATE
MyTable
SET
name = ICap(name)
To fix the database with only one sql statement use this:
UPDATE country_table SET country_name = CONCAT(UCASE(MID(country_name,1,1)),MID(LOWER(country_name),2));
This will uppercase the first letter of each country name and lowercase the rest. All without needing any PHP at all.
->The easiest way to edit a value inside a mySQL table
UPDATE TABLE SET COL="NEW VALUE" where COL="OLD VALUE";
Be careful, it will replace all line wher COL is equal to OLd VALUE
->easiest PHP way to capitalize the first letter of every word (space separated) inside a script
There's a function for that : http://php.net/manual/en/function.ucwords.php
To Edit the values in in the database just run a Update Query (I don't know how your table is designed) from php -- http://www.w3schools.com/php/php_mysql_intro.asp.
To Capitalize the first character of every word you can use ucwords.
You can do it all in mysql if you want:
SELECT CONCAT(UPPER(SUBSTRING(CountryName, 1, 1)), LOWER(SUBSTRING(CountryName FROM 2))) from countries AS properCountryname;
The resultset returned would be your CountryName field with uppercased first letter.
You coud even do the update in one sql query, if you wanted.
If you really want php to do the job, something like this:
<?php
set_time_limit(0);
$cnt=0;
$con=mysql_connect('localhost','root','');
mysql_select_db('fakeDB',$con);
$query="SELECT `name`,id FROM countries";
$result=mysql_query($query);
while ($row=mysql_fetch_array($result))
{
$name= $row["name"];
$key = $row["id"];
$field = strtolower($name);
$array=explode(" ",$name);
for ($i=0;$i<count($array);$i++)
{
$array[$i] = ucfirst($array[$i]);
}
$field = implode(" ",$array);
$query2 = "UPDATE countries SET `name`='$name' where id=$key";
mysql_query($query2);
$cnt++;
}
echo $cnt." Records updated";
?>
Just a quick untested thingie but it should give you an idea.