I am having a problem with my MySQL.
I have everything setup and all is well, but when I submit my form it will only work if the table is completely empty. It will not submit another entry if there is already information stored in the table.
here is the mysql table
CREATE TABLE student
(StudentID int NOT NULL,
StudentFirst varchar(30),
StudentLast varchar(30),
StudentEmail varchar(254),
StudentPhone varchar(12),
StudentDOB date,
DateStarted date,
LessonID int,
StudentAddress varchar(50),
StudentCity varchar(30),
StudentState char(2),
StudentZip varchar(10),
MusicInterest text);
alter table student add constraint StudentPK primary key AUTO_INCREMENT (StudentID);
alter table student add constraint LessonFK foreign key (LessonID) references lesson(LessonID);
This is my PHP
if(isset($_REQUEST['action'])){
switch($_REQUEST['action']){
case 'submit_student':
$first = $_REQUEST['StudentFirst'];
$last = $_REQUEST['StudentLast'];
$email = $_REQUEST['StudentEmail'];
$phone = $_REQUEST['StudentPhone'];
$dob = $_REQUEST['StudentDOB'];
$datestarted = $_REQUEST['DateStarted'];
$lessonid = $_REQUEST['LessonID'];
$address = $_REQUEST['StudentAddress'];
$city = $_REQUEST['StudentCity'];
$state = $_REQUEST['StudentState'];
$zip = $_REQUEST['StudentZip'];
$musicinterest = $_REQUEST['MusicInterest'];
$stmt = $dbh->prepare("insert into student (StudentFirst, StudentLast, StudentEmail, StudentPhone, StudentDOB, DateStarted, LessonID, StudentAddress, StudentCity, StudentState, StudentZip,MusicInterest) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
$stmt -> bindParam(1,$first);
$stmt -> bindParam(2,$last);
$stmt -> bindParam(3,$email);
$stmt -> bindParam(4,$phone);
$stmt -> bindParam(5,$dob);
$stmt -> bindParam(6,$datestarted);
$stmt -> bindParam(7,$lessonid);
$stmt -> bindParam(8,$address);
$stmt -> bindParam(9,$city);
$stmt -> bindParam(10,$state);
$stmt -> bindParam(11,$zip);
$stmt -> bindParam(12,$musicinterest);
$stmt -> execute();
break;
and my EXTJs
function addStudent(){
Ext.Ajax.request ({
url: 'inc/template.php',
params: {action: 'submit_student',
StudentFirst:firstNameTextField.getValue(),
StudentLast:lastNameTextField.getValue(),
StudentEmail: emailTextField.getValue(),
StudentPhone:phoneNumberTextField.getValue(),
StudentDOB:Ext.util.Format.date(dateOfBirth.getValue(), 'Y-m-d'),
DateStarted:dateStarted.getValue(),
LessonID:dayTypeCombo.getValue(),
StudentAddress:streetTextField.getValue(),
StudentCity:cityTextField.getValue(),
StudentState:stateTextField.getValue(),
StudentZip:zipTextField.getValue(),
MusicInterest:musicInterest.getValue()
},
method: 'POST',
});
tabPanel.activate(studentGrid);
tabPanel.activate(scheduleGrid);
clearStudentForm();
I have no idea why it only submits one time. It is really baffling. It shows the post in firebug.
any help is much appreciated.
I am not sure about AUTO-INCREMENT statement at
alter table student add constraint StudentPK primary key AUTO_INCREMENT (StudentID);
Also i think, you should use this syntax for multiple columns. for one column use
CREATE TABLE student
(StudentID int NOT NULL PRIMARY KEY,
StudentFirst varchar(30),
...
Related
I have a simple table with two columns "referralID" & "studentID"
I can add like this
$stmt = $pdo->prepare('INSERT INTO referralStudents (referralID,studentID) VALUES (?, ?)');
$stmt->execute([$myID,$studentID]);
I'm trying to get the WHERE NOT EXISTS statement to work. If there is already a row with both "referralID" & "studentID" don't add.
Both of these don't work can you show me where I'm going wrong?
$stmt = $pdo->prepare('INSERT INTO referralStudents (referralID,studentID) VALUES (?, ?) WHERE NOT EXISTS (SELECT * FROM referralStudents WHERE referralID = ? and studentID = ?")');
$stmt->execute([$myID,$studentID,$myID,$studentID]);
$stmt = $pdo->prepare('INSERT INTO referralStudents (referralID,studentID) VALUES (?, ?) WHERE NOT EXISTS (referralID,studentID) VALUES (?, ?)');
$stmt->execute([$myID,$studentID,$myID,$studentID]);
You need a SELECT statement and not VALUES to apply the conditions of the WHERE clause:
INSERT INTO referralStudents (referralID,studentID)
SELECT ?, ?
FROM dual
WHERE NOT EXISTS (SELECT * FROM referralStudents WHERE referralID = ? and studentID = ?)
You may remove FROM dual if your version of MySql is 8.0+.
See a simplified demo.
If the fields are empty i bet they are NULL. A field filled with NULL is existing but its content is NULL (NULL doesnt mean empty or non existing). Maybe this is what you need:
INSERT INTO refferalStudents (refferalID, studentID) VALUES (?,?) WHERE refferalID IS NULL AND studentID IS NULL
Please help me out. I'm trying to insert the records in 2 tables, in 1st table I can insert but for the second table I can't.
I have 3 stored procedures
HotelInsert
GetAccommodationByName
AvailbiltyInsert
It seems like the 1st stored procedure is okay as I can get output in the first table but in the second table I can't get the last inserted id.
First stored procedure
DELIMITER $$
CREATE DEFINER=`kno`#`localhost` PROCEDURE `HotelInsert`(IN `ZIP` BIGINT, IN `Ammn` VARCHAR(255), IN `HotelName` VARCHAR(255), IN `Add1` VARCHAR(255), IN `Add2` VARCHAR(255), IN `Det` VARCHAR(255), IN `ContactPer` VARCHAR(255), IN `Contact` VARCHAR(255), IN `CEmail` VARCHAR(255), IN `Image` VARCHAR(255), IN `StarCateg` TINYINT)
NO SQL
DETERMINISTIC
INSERT INTO Accommodation(
AccommodationId,
AccommodationTypeId,
ZipId,
PackageId,
Amenities,
Name,
AddressOne,
AddressTwo,
AccommodationStatus,
Details,
ContactPerson,
StarCategory,
ImageGallery,
ContactPhone,
ContactEmail
)
VALUES(
NULL,
1,
ZIP,
4,
Ammn,
HotelName,
Add1,
Add2,
1,
Det,
ContactPer,
StarCateg,
Image,
Contact,
CEmail
)$$
DELIMITER ;
Second stored procedure:
DELIMITER $$
CREATE DEFINER=`kno`#`localhost` PROCEDURE `GetAccomodationIdByName`(IN `AccommodationName` VARCHAR(255), OUT `AccId` INT)
NO SQL
DETERMINISTIC
SELECT AccommodationId into AccId from Accommodation where Name=AccommodationName$$
DELIMITER ;
Third stored procedure:
DELIMITER $$
CREATE DEFINER=`kno`#`localhost` PROCEDURE `AvailabilityInsert`(IN `AccId` INT, IN `RTypeId` INT, IN `AvailableRooms` INT, IN `Charges` BIGINT, IN `AvailDate` DATE)
NO SQL
INSERT INTO AccommodationAvailabilty (AvailableId, AccommodationId, RoomTypeId, Available, Price, AvailableDate) VALUES (NULL, AccId, RTypeId, AvailableRooms, Charges, AvailDate)$$
DELIMITER ;
PHP code:
$sql = $db->prepare('CALL HotelInsert(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
$sql->bind_param('dssssssssss', $ZipId, $Amenities, $Name, $AddressOne, $AddressTwo, $Details, $ContactPerson, $ContactPhone, $ContactEmail , $target_path, $StarCategory);
$sql->execute();
$select = $db->query('SELECT #ZIP,#Ammn, #HotelName, #Add1, #Add2, #Det, #ContactPer,#Contact,#CEmail,#Image, #StarCateg');
$result = $select->fetch_assoc();
$ZipId = $result['#ZIP'];
$Amenities = $result['#Ammn'];
$AccommodationName = $result['#HotelName'];
$AddressOne = $result['#Add1'];
$AddressTwo = $result['#Add2'];
$Details = $result['#Det'];
$ContactPerson = $result['#ContactPer'];
$ContactPhone = $result['#Contact'];
$ContactEmail = $result['#CEmail'];
$target_path = $result['#Image'];
$StarCategory = $result['#StarCateg'];
//Hotel Calling AccommodationId by AccommodationName with GetAccomodationIdByName(); stored procedure.
$sql = $db->prepare('CALL GetAccomodationIdByName(?)');
$sql->bind_param('s', $AccommodationName);
$sql->execute();
$select = $db->query('SELECT #AccId');
$result = $select->fetch_assoc();
$AccommodationId = $result['#AccId'];
//Hotel Insert RoomType by calling AvailabilityInsert(); Store procedure.
$sql = $db->prepare('CALL AvailabilityInsert(?,?,?,?,?)');
$sql->bind_param('iiids', $AccommodationId, $RoomTypeId, $Available, $Price, $AvailableDate);
$sql->execute();
$select = $db->query('SELECT #AccId,#RTypeId, #AvailableRooms, #Charges, #AvailDate');
$result = $select->fetch_assoc();
$AccommodationId = $result['#AccId'];
$RoomTypeId = $result['#RTypeId'];
$Available = $result['#AvailableRooms'];
$Price = $result['#Charges'];
$AvailableDate = $result['#AvailDate'];
header("Location: ../hotel-all.php?id=$Name");
exit();
I have to make a query, which inserts-or-updates in 1 line.
EDIT: I add the WORKING SQL query here.
$this->sqlSavePlot = $this->db->prepare(
"INSERT OR REPLACE INTO plots (id, level, X, Z, name, owner, helpers, denied, biome) VALUES
((select id from plots where level = :level AND X = :X AND Z = :Z),
:level, :X, :Z, :name, :owner, :helpers, :denied, :biome);"
);
Theoretically i want the same stuff in prepared MySQL statements
Currently the mess looks like this:
$this->sqlSavePlot = $this->db->prepare(
"INSERT INTO plots (`id`, `level`, `X`, `Z`, `name`, `owner`, `helpers`, `denied`, `biome`)
VALUES(id = (SELECT id FROM plots WHERE level = level AND X = VALUES(X) AND Z = VALUES(Z)), level = ?, X = ?, Z = ?, name = ?, owner = ?, helpers = ?, denied = ?, biome = ?)
ON DUPLICATE KEY UPDATE
id = VALUES(id),
level = VALUES(level),
X = VALUES(X),
Z = VALUES(Z),
name = VALUES(name),
owner = VALUES(owner),
helpers = VALUES(helpers),
denied = VALUES(denied),
biome = VALUES(biome);"
);
As you see, quite chaotic.
This is how the database looks like:
So in theory, if the user executes the savePlot function, several fields are replaced, like you can see in the PHP code. "sqlSavePlot" is the query i showed above
For some deeper explanation some PHP code:
public function savePlot(Plot $plot): bool{
print "------------------------------------------------------".PHP_EOL;
$this->db->ping();
$helpers = implode(',', $plot->helpers);
$denied = implode(',', $plot->denied);
if ($plot->id <= 0){
$stmt = $this->sqlSavePlot;
$stmt->bind_param('siisssss', $plot->levelName, $plot->X, $plot->Z, $plot->name, $plot->owner, $helpers, $denied, $plot->biome);
} else{
$stmt = $this->sqlSavePlotById;
$stmt->bind_param('isiisssss', $plot->id, $plot->levelName, $plot->X, $plot->Z, $plot->name, $plot->owner, $helpers, $denied, $plot->biome);
}
$result = $stmt->execute();
var_dump($stmt);
var_dump($result);
var_dump($plot);
$this->lastSave = time();
if ($result === false){
$this->plugin->getLogger()->error($stmt->error);
return false;
}
$this->cachePlot($plot);
return true;
}
A plot's id can either be -1 if "empty", or have an ID which is fetched from the savePlot function
I know that the messed up part is around the first "Values":
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 '?, X = ?, Z = ?, name = ?, owner = ?, helpers = ?, denied = ?,
biome = ?)
' at line 2
Could someone explain me what i could put instead?
EDIT: as requested, SHOW CREATE TABLE
CREATE TABLE `plots` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`level` text COLLATE utf8_unicode_ci,
`X` int(11) DEFAULT NULL,
`Z` int(11) DEFAULT NULL,
`name` text COLLATE utf8_unicode_ci,
`owner` text COLLATE utf8_unicode_ci,
`helpers` text COLLATE utf8_unicode_ci,
`denied` text COLLATE utf8_unicode_ci,
`biome` text COLLATE utf8_unicode_ci,
PRIMARY KEY (`id`),
KEY `XZ` (`X`,`Z`)
) ENGINE=InnoDB AUTO_INCREMENT=3609 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
I think you want something more like this:
INSERT INTO plots (`id`, `level`, `X`, `Z`, `name`, `owner`, `helpers`, `denied`, `biome`)
SELECT id, p.level, p.X, p.Z, ?, ?, ?, ?
FROM plots p
WHERE p.level = ? AND X = ? AND Z = ?
ON DUPLICATE KEY
UPDATE name = VALUES(name),
owner = VALUES(owner),
helpers = VALUES(helpers),
denied = VALUES(denied),
biome = VALUES(biome);
You need to be careful about the order of the arguments. I am guessing that id is the primary key and (X, Z, level) is declared as unique (how you identify duplicates). You only specify that you want to change name in the event of a collision, but this sets all the values (as in your version).
Fixed up my Query with the answer provided by #Gordon Linoff
Turns out i even had a logical issue.. i mixed up the "saveByID" and "saveByXZ"..
public function savePlot(Plot $plot): bool{
$this->db->ping();
$helpers = implode(',', $plot->helpers);
$denied = implode(',', $plot->denied);
if ($plot->id >= 0){
$stmt = $this->sqlSavePlotById;
$stmt->bind_param('isiisssss', $plot->id, $plot->levelName, $plot->X, $plot->Z, $plot->name, $plot->owner, $helpers, $denied, $plot->biome);
} else{
$stmt = $this->sqlSavePlot;
$stmt->bind_param('siisiisssss', $plot->levelName, $plot->X, $plot->Z, $plot->levelName, $plot->X, $plot->Z, $plot->name, $plot->owner, $helpers, $denied, $plot->biome);
}
$result = $stmt->execute();
$this->lastSave = time();
if ($result === false){
$this->plugin->getLogger()->error($stmt->error);
return false;
}
$this->cachePlot($plot);
return true;
}
The fixed up query:
$this->sqlSavePlot = $this->db->prepare(
"INSERT INTO plots (`id`, `level`, `X`, `Z`, `name`, `owner`, `helpers`, `denied`, `biome`)
VALUES((SELECT id
FROM plots p
WHERE p.level = ? AND X = ? AND Z = ?),?,?,?,?,?,?,?,?)
ON DUPLICATE KEY
UPDATE name = VALUES(name),
owner = VALUES(owner),
helpers = VALUES(helpers),
denied = VALUES(denied),
biome = VALUES(biome);"
);
$this->sqlSavePlotById = $this->db->prepare(
"UPDATE plots SET id = ?, level = ?, X = ?, Z = ?, name = ?, owner = ?, helpers = ?, denied = ?, biome = ? WHERE id = VALUES(id);"
);
Thanks alot to everyone! Hope this helps others in the future!
I have two tables which store the same data. One is for active users and the other for inactive users. When a user comes, it is searched in the active table and if not found, it is searched in the inactive table. If the user info is found in the inactive table, then it should be moved to active table and deleted from inactive table.
The tables have a column that stores a photograph. When I try to insert the information to active table, I get the following error:
SQLSTATE[22018]: [Microsoft][SQL Server Native Client 11.0][SQL Server]Operand type clash: nvarchar(max) is incompatible with image
I am sure it is caused by the photo because if the user info does not have a photo, the move is successful. But when there is a photo, it fails with the above error.
The SQL that creates the table:
CREATE TABLE [dbo].[tblBackup](
[Id] [int] IDENTITY(1,1) NOT NULL,
[DriverId] [int] NULL,
[FirstNameAmh] [nvarchar](100) NULL,
[FatherNameAmh] [nvarchar](100) NULL,
[GrandNameAmh] [nvarchar](100) NULL,
[Photo] [image] NULL
)
Here is the code:
$dbc->beginTransaction();
$sql = "select * from tblBackup where Id=?";
$stmt = $dbc->prepare($sql);
$stmt->bindParam(1, $_GET["gid"]);
$stmt->execute();
$row = $stmt->fetch();
$ins = "insert into tblActive(Id, DriverId, FirstNameAmh, FatherNameAmh, GrandNameAmh, Photo) values(?, ?, ?, ?, ?, ?)";
$st = $dbc->prepare($ins);
$val = array($row['Id'], $row['DriverId'], $row['FirstNameAmh'], $row['FatherNameAmh'], $row['GrandNameAmh'], $row['Photo']);
$st->execute($val);
$sql = "delete from tblBackup where Id=?";
$stmt = $dbc->prepare($sql);
$stmt->bindParam(1, $_GET["gid"]);
$stmt->execute();
$dbc->commit();
Edit:
I concluded that the photo data retrieved by PHP is being treated as nvarchar(max) type rather than image type by SQL server. Because of this, SQL server is complaining that it could not insert nvarchar(max) in image data type column. Is there a way to solve this?
If you are in the development phase, I think it would be better to create a stored procedure including "insert select" with "gid" as the parameter and execute it from php. Can't it be a solution for you?
I changed the code a little bit and now it is working. It is seems the problem is cause by prepared statement, though I don't understand why.
$dbc->beginTransaction();
$sql = "select * from tblBackup where Id=?";
$stmt = $dbc->prepare($sql);
$stmt->bindParam(1, $_GET["gid"]);
$stmt->execute();
$row = $stmt->fetch();
$ins = "insert into tblActive(Id, DriverId, FirstNameAmh, FatherNameAmh, GrandNameAmh, Photo) values(?, ?, ?, ?, ?, ".$dbc->quote($row['Photo']).")";
$st = $dbc->prepare($ins);
$val = array($row['Id'], $row['DriverId'], $row['FirstNameAmh'], $row['FatherNameAmh'], $row['GrandNameAmh']);
$st->execute($val);
$sql = "delete from tblBackup where Id=?";
$stmt = $dbc->prepare($sql);
$stmt->bindParam(1, $_GET["gid"]);
$stmt->execute();
$dbc->commit();
I have a little problem with MySQL query. I'm using PDO queries, which now just insert values into the tables (see below):
$stmt = $dbh -> prepare("INSERT INTO tmp (user_id, test_id, question_id, answer_id) VALUES (?, ?, ?, ?)");
$stmt -> bindParam(1, $_SESSION['UserID']); // binds parameter for user id
$stmt -> bindParam(2, $_GET['start_test']); // binds parameter for test id
$stmt -> bindParam(3, $_POST['question']); // binds parameter for selected answer
$stmt -> bindParam(4, $_POST['select_answer']); // binds parameter for selected answer
$stmt -> execute();
tmp table structure is the following:
CREATE TABLE IF NOT EXISTS `tmp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`test_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`question_id` int(11) NOT NULL,
`answer_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
)
I want to insert answer_id value if it's wasn't there and check if user_id at the same time, otherwise just update, example:
I have two users with user_id=1 and user_id=2, they're answering the questions and every answer for each student stores separately. User_id=1 picked answer_id = 3 and user_id=2 picked the answer_id = 3. However, then one user realised this was a wrong answer and wants to change it to another one (suppose answer_id=2), I want the query update the current answer_id=3 WHERE user_id=1 to answer_id=2
You can make an INSERT IGNORE for the same, which looks simpler and will be atomic with some issues.
Step are like
Create a unique index on (user_id,question_id, answer_id)
ALTER TABLE tmp add index user_qn_ans_idx (user_id,question_id, answer_id);
Now just do the insert, and probably on duplicate key update as well
INSERT INTO tmp (user_id,question_id, answer_id) values
(, , )
ON DUPLICATE KEY UPDATE answer_id = VALUES(answer_id)
Add a select count and do conditionals below:
$stmt = $dbh->prepare("SELECT count( 1 ) FROM tmp WHERE user_id = :user_id AND question_id = :question_id and answer_id = :answer_id");
$stmt->bindValue( 'user_id', 1 );
$stmt->bindValue( 'question_id', 1 );
$stmt->bindValue( 'answer', 1 );
$stmt->execute();
$oExists = $stmt ->fetch();
if( !empty( $oExists ) )
{
// Run update sql...
}
else
{
// Run insert sql...
$stmt = $dbh->prepare("SELECT count( 1 ) FROM tmp WHERE user_id = :user_id AND question_id = :question_id AND answer_id = :answer_id");
$stmt->bindValue( 'user_id', 1 );
$stmt->bindValue( 'question_id', 1 );
$stmt->bindValue( 'answer_id', 1 );
$stmt->execute();
$oExists = $stmt ->fetch();
if( !empty( $oExists ) ) {
echo "update";
$stmt = $dbh->prepare("UPDATE tmp SET answer_id = :answer_id WHERE user_id = {$_SESSION['UserID']} AND question_id = {$_POST['question']}"); //updates the counter each time test created
$stmt -> bindParam(':answer_id', $_POST['select_answer'], PDO::PARAM_INT);
$stmt -> execute();
} else {
echo "insert";
$stmt = $dbh -> prepare("INSERT INTO tmp (user_id, test_id, question_id, answer_id) VALUES (?, ?, ?, ?)");
$stmt -> bindParam(1, $_SESSION['UserID']); // binds parameter for user id
$stmt -> bindParam(2, $_GET['start_test']); // binds parameter for test id
$stmt -> bindParam(3, $_POST['question']); // binds parameter for selected answer
$stmt -> bindParam(4, $_POST['select_answer']); // binds parameter for selected answer
$stmt -> execute();
}
Here is always updates, but not inserts..