update cell value if value not already in - php

I have to update the column File on the TABLE TEST. This column contains the files related to the row. Each file is separated by a |.
An example could be
ID NAME FILE
1 apple fruit.png | lemon.png
Now when I add a new file to the FILE column I use this query:
$link->query("UPDATE TEST SET File = CONCAT(File, '$dbfilename') WHERE id = '$p_id'")
where $dbfilename can be e.g. pineapple.jpg |
The problem is that, if $dbfilename is already on the File values, it will be added another time, resulting double.
How can I check if File contains already $dbfilename, and if yes, don't add id, or even don't execute the query?

This is not a good way of storing information in a database. But I'll get to that in a second. To directly answer your question, you could use this as your SQL query:
UPDATE TEST SET File = CONCAT(File, '$dbfilename')
WHERE id='$p_id'
AND File NOT LIKE '%$dbfilename%'
AND Lingua='$linguadilavoro'
However, this may cause some issues when one file pineapple.jpg and you try to add another-pineapple.jpg
Really, I think you should consider how this is a horribly bad approach to databases. Consider breaking the files off into a second table. For example:
# a table for the fruit names
CREATE TABLE fruits (
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(250) NOT NULL,
UNIQUE INDEX(name)
);
# a table for file names
CREATE TABLE files (
fileid INT UNSIGNED NOT NULL DEFAULT PRIMARY KEY AUTO_INCREMENT,
fruitid INT UNSIGNED,
filename VARCHAR(250),
UNIQUE INDEX(fruitid, filename)
);
# find all of the fruits with their associated files
SELECT fruits.id, fruits.name, files.filename
FROM fruits LEFT JOIN files ON fruits.id=files.fruitid
# add a file to a fruit
INSERT INTO files (fruitid, filename)
VALUES ('$fruitID', '$filename')
ON DUPLICATE KEY UPDATE fruitid=LAST_INSERT_ID(id)

You will have to select out the FILE for the id.
then use explode to break it into an array
then check use in_array to determine if it should be added or not
Here is some (untested) code for guidance
$stmt = $link->query("SELECT File File from TEST WHERE id = '$p_id'");
$rec = $stmt->fetchAssoc();
$files = explode(" | ",$rec["FILE"]);
if (!in_array($dbfilename, $files)){
// add to FILE
} else {
// it's already there
}

I would redesign your table structure and add a new table File with the following columns instead of using a varchar field for multiple values:
Table Test
TableId, Name
Table File
FileId, TestId, FileName

Related

How to Bulk insert with a dynamic value for a column

the situation is this:
I have 200 txt files with different names like 601776.txt each file's name is actually an ID_foo and it contains some data like this (2 columns):
04004 Albánchez
04006 Albox
04008 Alcóntar
04009 Alcudia de Monteagud
.
.
.
now I wanna BULK INSERT these TXT files into a SQL Server Table which has 3 column one of these columns should be the name of the txt file. I'm using a PHP script, so I made a loop to get the file names and then what?
BULK INSERT Employee_Table
FROM '../home/601776.txt'
WITH (
FIELDTERMINATOR ='\t',
ROWTERMINATOR = ''\n''
)
how can i set the third column while bulk inserting with $file_name variable in each loop?
Do you think it is a better idea if it is possible to insert the table by reading the txt file line by line? And how?
Thanks
This is one of the few times that a cursor is actually ideal in SQL Server. Here's a way. Once you see the PRINT statement and are satisfied you can comment it out and uncomment out the two lines below it. I put some logic in to add the file name and a processed date which is usually needed, but your table definition would need these columns. It should get the idea across.
---------------------------------------------------------------------------------------------------------------
--Set some variables
---------------------------------------------------------------------------------------------------------------
DECLARE #dt VARCHAR(10) --date variable but stored as VARCHAR for formatting of file name
DECLARE #fileLocation VARCHAR(128) = 'E:\DATA_TRANSFERS\' --production location which is \\issqlstd01 but the xp_dirtree didn't like this
DECLARE #sql NVARCHAR(4000) --dynamic sql variable
DECLARE #fileName VARCHAR(128) --full file name variable
---------------------------------------------------------------------------------------------------------------
--Get a list of all the file names in the directory
---------------------------------------------------------------------------------------------------------------
IF OBJECT_ID('tempdb..#FileNames') IS NOT NULL DROP TABLE #FileNames
CREATE TABLE #FileNames (
id int IDENTITY(1,1)
,subdirectory nvarchar(512)
,depth int
,isfile bit)
INSERT #FileNames (subdirectory,depth,isfile)
EXEC xp_dirtree #fileLocation, 1, 1
---------------------------------------------------------------------------------------------------------------
--Create a cursor to fetch the file names
---------------------------------------------------------------------------------------------------------------
DECLARE c CURSOR FOR
select subdirectory from #FileNames where isfile = 1
OPEN c
FETCH NEXT FROM c INTO #fileName
---------------------------------------------------------------------------------------------------------------
--For each file, bulk insert
---------------------------------------------------------------------------------------------------------------
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = 'BULK INSERT Employee_Table FROM '''+ #fileLocation + #fileName +''' WITH (FIELDTERMINATOR = ''\t'',KEEPNULLS,ROWTERMINATOR = ''0x0a'')'
--Try the bulk insert, if error is thrown log the error
--Also update the Table Columns which aren't a part of the original file (load date and original file name)
BEGIN TRY
PRINT(#sql)
--EXEC(#sql)
--UPDATE Employee_Table SET OrigFile = #fileName, LoadDate = GETDATE() WHERE OrigFile IS NULL
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
END CATCH
FETCH NEXT FROM c INTO #fileName
END
CLOSE c
DEALLOCATE c
GO

Send null if key does not exists

I have csv files what i parse to array and pass to mysql table.
Some CSV files does not contains some columns what are in database and when i convert it to array than i have smaller number of columns that are in table and i get "syntax error".
From controller i call:
function sendHistoric(){
$this->load->model('Historic_model');
$this->load->library('csvreader');
foreach($this->divisions as $div){
$result = $this->csvreader->parse_file("assets/csv/1516{$div}.csv");//path to csv file
$this->Historic_model->loadCSVtoDB($result);
//var_dump($result);
}
}
in model i have:
function loadCSVtoDB($data){
$sql = "call ins_historic(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
foreach($data as $row){
var_dump($row);
$this->db->query($sql,$row);
}
//echo $this->db->conn_id->error_message();
}
Can i somehow send NULL instead where he find that i have smaller number of data or i need to check if each element of array exists, if not that set it to null?
One option to consider is not writing slower PHP looping but to harness the flexible code possibilties inside a LOAD DATA INFILE block, such as the processing seen in this answer link here. The functions, conversions possible are endless.
Maybe 6 of one, half dozen of another. But nice for simpler routines too, and I would suggest a fast data ingest.
Edit: (based on OP comment below)
create table t62
( c1 int not null,
c2 varchar(10) not null,
c3 int not null,
c4 char(5) not null,
someOther int not null,
-- an addtion 57 columns here
primary key(c1,c2,c3,c4)
);
-- Mimic the LOAD DATA INFILE or PHP loop:
insert t62(c1,c2,c3,c4,someOther) values (1,'t',1,'01742',777);
insert t62(c1,c2,c3,c4,someOther) values (1,'t',1,'01742',777); -- error 1062: Dupe PK
insert t62(c1,c2,c3,c4,someOther) values (1,'t',2,'01742',777); -- happy
So I don't know, how would you suggest code would pick that composite PK for you? If so, how would that made-up-data play with its relationships with other data?

LIKE % XX(YY)GG % not working in MySQL

I have used Stored procedure to check whether a name exist in a table or not by using the following code snippet..
BEGIN
IF ids = 0 THEN
SELECT * FROM table_name WHERE `table_id` = alb_id AND name LIKE CONCAT('%',var_name,'%');
END IF;
END
I got the solution if the name doesn't contain any special characters or brackets, like XXXX.
If the name contains any brackets means result not came, like XX(YY)GG.
Suggest me for the best solution
Edited:
In this if a name exist already i should not insert it again, for this condition i used this procedure. If it returns mysql_num_rows > 0 means i wont insert, else i will insert the name into my table..
My sample names are,..
Turning Tables (Live Acoustic)
Hiding My Heart
Someone Like You (Live Acoustic)
Right Now (Na Na Na)
Keep You Much Longer
Someone Like You
In the list of name "Someone Like You" and "Someone Like You (Live Acoustic)" are two different names, i want to identify the name "Someone Like You (Live Acoustic)" is already exist or not..
How do i do?
CREATE TABLE `stack_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB CHARSET=utf8;
INSERT INTO `blur_new`.`stack_test` (`id`, `text`) VALUES ('1', 'run (rabbit) run');
INSERT INTO `blur_new`.`stack_test` (`id`, `text`) VALUES ('2', 'test');
set #a = 'n (rabbit)';
select * from stack_test where text like concat('%',#a,'%');
results in:
1 |run (rabbit) run
So, it works.
check the rest of the conditions in where clause
check how are you passing the value
you might gonna have to check you data types. I have a feeling something is not right there

CREATE TABLE fails when i use an integer name for column

I'm trying to create a dynamic form builder. Therefore PHP gets a set of names from a database and creates a new table with those names as column names. This works quite well until one or more names are integer (for ex. '12345'). Then the script fails.
How can I force PHP of MySQL to give numeric table names?
Here is a piece of the code (its still a draft):
$slaop = 'id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id)';
require_once 'dbconnect.php';
$connector = new DbConnector();
$result = $connector->query( 'SELECT * FROM '.$form.' ORDER BY rang' );
while ($opslaan = $connector->fetchArray($result)){
$slaop .= ', ';
$slaop .= $opslaan['tekstid'];
$slaop .= ' TEXT';
}
echo $slaop;
// OPSLAAN
$formnaam = $_GET['welkform'];
require_once 'dbconnectsave.php';
$connector = new DbConnectorSave();
$connector->query('CREATE TABLE '.$formnaam.'('.$slaop.')')
or die(mysql_error());
$opslaan['tekstid']; is the part where the text of integer are called.
Does anyone have an idea?
Why not prefix all tables with the form name? Then integers don't matter...
As others have noted, this may not be a good idea.
However, you can still do it if the column name is surrounded in backticks. Here's a couple of MySQL examples:
create table abc (id int, 123 int); -- fails
create table abc (id int, `123` int); -- succeeds
How can i force php of mysql to give numeric table names?
May be you can force your application not to use such field names?
And also change the whole design as well, without employing dynamically created tables, and use more usual approach of storing table structure in some table?
Use a prefix that starts with a letter for your column names.

creating DB table by giving input from php text box

I want to make a table in a database, by giving the name of that table as an input from a text box.
<?php
$tablename = $_POST['tablename'];
// Create a MySQL table in the selected database
mysql_query("CREATE TABLE $tablename(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
firstpublish VARCHAR(255),
descriptions VARCHAR(255))") or die(mysql_error());
?>
it makes the table and the field, but i can't insert any data in it. When i run the code below
<?php
$firstpublish = $_POST['firstpublish'];
$descriptions = $_POST['descriptions'];
if(isset($_POST['firstpublish']) || ($_POST['descriptions']))
{
$order="INSERT INTO $tablename (id,firstpublish,descriptions) VALUES ('','$firstpublish','$descriptions')";
$result = mysql_query($order) or die (mysql_error());
}
?>
it showing an error message
"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), firstpublish VARCHA' at line 1"
how can i fixed this problem.
-thankyou.
My best guess would be that your first query is somehow being rerun with a blank value for $tablename
If this is a publicly accessible page, i'd be very careful about creating tables from user input. You also probably want to (at the very least) run $tablenale through mysql_real_escape_string() and change CREATE TABLE to CREATE TABLE IF NOT EXISTS
The error is here:
mysql_query("CREATE TABLE $tablename(
Since you are mixing a variable in a quoted string, you insert whitespace after its name, because "$tablename(" is illegal name and will most likely be replaced will null, so the SQL-statement will actually be seen for MySQL as
CREATE TABLE id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), firstpublish VARCHAR(255), descriptions VARCHAR (255))
which, in turn, is a syntax error.
Solution: Add a space between $tablename and "(".

Categories