DateTime Null and mySql - php

I constantly run into this and there has to be a better way to do it. So I have an Order Class and an Order_db class. in the order class there is a property $orderDate that is a DateTime object.
The problem is that sometimes the $orderDate is null. So it seems I have to options:
When I do a select query I test to see if there was date before calling my setter. When I do an Insert query I check that $orderDate isn't null before trying to perform a ->format (as that would throw an error)
I test in the setter if anything was passed before creating a new DateTime object but I'm still stuck with testing if it exists before using it with ->format.
It's not that big of a deal but I deal with a lot of date fields and it gets pretty repetitive. Is there a better way to handle this? In my ideal world if I passed nothing to DateTime when creating a instance it would be null, and if I called ->format on a null DateTime it would return nothing instead of throwing an error.

try this:
CREATE TABLE IF NOT EXISTS `DB`.`Exampletable` (
`field_1` VARCHAR(255) NOT NULL DEFAULT '',
`field_2` CHAR(20) NOT NULL default 'default_text',
`field_3` INT(10) DEFAULT NULL,
`field_4` BIGINT(20),
`field_5` DATETIME DEFAULT NULL
);
Do you tried to add the Default NULL to the date's?

Related

Splitting a string with Swift using a PHP-equivalent regular expression (#\n\s*\n#Uis)

I need to split a given multi-line string (sample here) using a regular expression with Swift. With PHP (the language I use for building web applications) I do this (after removing comments and substituting some tokens):
// split the file contents in fragments
$fragments = preg_split("#\n\s*\n#Uis", $contents);
And this is what I get if execute preg_split over the code sample:
Array
(
...
[2] =>
CREATE TABLE IF NOT EXISTS c_search_history (
entry_id BIGINT(64) UNSIGNED NOT NULL AUTO_INCREMENT,
entry_date_added DATETIME NOT NULL,
entry_language CHAR(2) NOT NULL DEFAULT 'es',
entry_query TEXT NOT NULL,
PRIMARY KEY (entry_id),
INDEX (entry_date_added),
INDEX (entry_language)
) ENGINE=InnoDB DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
[3] =>
CREATE TABLE IF NOT EXISTS c_search_weight_entries (
entry_id BIGINT(64) UNSIGNED NOT NULL AUTO_INCREMENT,
entry_date DATETIME NOT NULL,
entry_model VARCHAR(175) NOT NULL,
entry_model_id BIGINT(64) UNSIGNED NOT NULL,
entry_value DOUBLE NOT NULL,
PRIMARY KEY (entry_id),
INDEX (entry_date),
INDEX (entry_model),
INDEX (entry_model_id),
INDEX (entry_value)
) ENGINE=InnoDB DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
...
)
The goal for this is to take an .sql file and flatten its contents so each function, table, procedure, trigger or view definition becomes a one-liner for later execution. The problem is I'm fairly new to Swift and I haven't been able to translate the #\n\s*\n#Uis regular expression into something usable for NSRegularExpression.
I tried to use this solution but it outputs nothing for me (but I may be that I have used it in the wrong way or I don't understand how it really works).
Can you give me a hint? Any help would be greatly appreciated :)
After doing, undoing and trying different approaches, seems the only thing I needed to do was to substitute #\n\s*\n#Uis with \\n\\s*\\n and it worked. I still need to do some serious research on NSRegularExpression and a lot of other Swift concepts but, for now, that did the trick :)

How to set datetime field in the symphony 3 for update or insert data?

I am trying to set the date and time field in the symfony 3.4 in this way:
$eventProject = new $eventProject();
$eventProject->setDateFrom('2018-05-09');
when I save the values, It is giving me error like:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'dateFrom' can
not be null
In ConversionException.php line 95:
Could not convert PHP value '2018-05-09' of type 'string' to type 'datetime
'. Expected one of the following types: null, DateTime
I could not understand what is wrong ?
You need to use PHP's DateTime object to set the date.
$eventProject = new $eventProject();
$date = new \DateTime('2018-05-09');
$eventProject->setDateFrom($date);
This also means that you have to work with DateTime when retrieving the date.
$date = $eventProject->getDate();
var_dump($date->format("Y-m-d"));
//string(10) "2018-05-09"
Be sure to use format on a retrieved DateTime object when you want to get the date as a string.
This is more about how the eventProject class/entity is written and not something that is forced by Symfony. That being said it is quite a common way to work with time in PHP projects. In the beginning it can seem a little awkward but as you get used to it you will find DateTime to be pretty handy.

MSSQL Server INSERT NULL, but insert GetDate() in DATETIME

I am migrating a database from MySQL to MSSQL.
[MySQL] I have a CHANGEDATE column that is of TIMESTAMP with default CURRENT_TIMESTAMP
[MSSQL] I have the same CHANGEDATE column that is of DATETIME and added a default constraint of GETDATE()
The codebase is PHP using CodeIgniter. I want the column to always be set so I don't allow NULL in either DBMS.
When I insert with MySQL, the property of the PHP model CHANGEDATE defaults to NULL. This triggers the default and the column entry is set to CURRENT_TIMESTAMP. The same code when configured to MSSQL however throws an error that NULL is not allowed in the column, which is valid, but I would rather MSSQL function like MySQL and insert the value of GETDATE() in that instance.
If I do unset($model->CHANGEDATE) or delete the property from my model, then it works as expected, but I wanted to know if there was a way to solve this just using MSSQL instead of updating all my PHP models.
class model {
public $CHANGEDATE;
...
}
ERROR (as described):
[Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Cannot insert the value NULL into column 'CHANGEDATE'; column does not allow nulls. INSERT fails.
INSERT INTO Logs (..., CHANGEDATE, CHANGEBY) VALUES (..., NULL, NULL)
UPDATE:
CI should create support for DBMS specific keywords as #steoleary stated in his answer(for which I marked his correct). However, I found the best solution in my case was to slightly modify the core class DB_active_rec.php
function set(...){
...
foreach ($key as $k => $v)
{
if (is_null($v)) continue;
...
}
}
I assume that you already have the default set on your SQL server column and you don't allow NULLs, deafult constraints won't fire on a NULL value, they will only fire when no value is specified, or if you specify to insert the default value on insert like this:
INSERT INTO [dbo].[table]
([col1]
,[col2]
,[col3]
,[col4]) --Column with default constraint
VALUES
('bob',
'bobson',
1,
DEFAULT) --default keyword
Doing that will cause the default to fire and you shouldn't have to change your models.
I don't know how to express this in code igniter, but in SQL Server, it is really easy:
create table . . . (
changedate not null datetime default getdate()
)
No trigger is required.

Switch from mySQL to mariaDB timestamp messup

I have switched from MySQL to MariaDB which has caused some "minor" problems. One has been bugging me for hours now and i can't find the solution.
I moved my database by exporting it from MySQL and importing it into MariaDB which went well..
When one of my update queries did not work i narrowed it down to this function in my database handler:
public function updateEquipment($type,$product,$acquisition,$calibration_interval,$equipment_no,$inspection_date,$equipment_id,$active)
{
$stmt = $this->conn->prepare("UPDATE equipment SET type = :type, acquisition = :acquisition, calibration_interval = :calibration_interval, equipment_no = :equipment_no, product = :product, inspection_date = :inspection_date, active = :active WHERE id = :equipment_id");
$stmt->bindParam(":equipment_id", $equipment_id,PDO::PARAM_INT);
$stmt->bindParam(":type", $type,PDO::PARAM_STR);
$stmt->bindParam(":acquisition", $acquisition,PDO::PARAM_STR);
$stmt->bindParam(":calibration_interval", $calibration_interval,PDO::PARAM_STR);
$stmt->bindParam(":equipment_no", $equipment_no,PDO::PARAM_STR);
$stmt->bindParam(":product", $product,PDO::PARAM_STR);
$stmt->bindParam(":inspection_date", $this->formatDateStrToTimeStamp($inspection_date),PDO::PARAM_STR);
$stmt->bindParam(":active", $active,PDO::PARAM_INT);
return $stmt->execute();
}
formatDateStrToTimeStamp function:
private function formatDateStrToTimeStamp($inspection_date)
{
$day = substr($inspection_date,0,2);
$month = substr($inspection_date,3,2);
$year = substr($inspection_date,6,4);
return date('Y-m-d H:i:s', strtotime($year."-".$month."-".$day));
}
As you can see, i have switched out the binding of my inspection_date with a string representing the timestamp i want to update. I tested the statement WITHOUT updating my timestamp and then it was working as expected. As soon as i add the timestamp (in my case i have inserted a static timestamp) the row will NOT update and execute does not return (it should return true or false).
Heres my table structure:
CREATE TABLE `equipment` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`type` text NOT NULL,
`acquisition` text NOT NULL,
`calibration_interval` text NOT NULL,
`equipment_no` text NOT NULL,
`product` text NOT NULL,
`inspection_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`active` int(11) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Question: Are timestamps treated different in mariaDB, because i have not made any changes to my code since the switch, and i have simply imported my database from the export i made from my MySQL database.
After debugging my pants off (because im not very good at debugging web applications) i finally found the answer to my problem.
PDO's bindparam must bind a variable to a placeholder or questionmark which is also stated in the pdo documentation. In my case i tried both inserting a string directly when binding, and the original code with the error used the return value of a timestamp formater. In both cases i didn't use a variable when binding to my placeholder, hence the error....
I came across the the error when i debugged the function using Chrome's Advanced Rest Client which revealed an error: "Only variables should be passed by reference".
Solution 1:
$inspect = $this->formatDateStrToTimeStamp($inspection_date);
$stmt->bindParam(":inspection_date", $inspect,PDO::PARAM_STR);
Solution 2:
As pointed out by Ryan Vincent in the comments use bindValue instead (see his comment for further inspiration)
But still a bit confused:
I'm still a bit confused though, as the code previously ran on another host without problems. I cannot remember the PHP version or anything, but if someone could confirm that it was possible in previous version it would explain why...

Is the method Doctrine_Table::find() deprecated?

I had a problem with the method Doctrine_Table::find(), since it's thorowing an exception of
SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
I solved the problem by using Doctrine::getTable('City')->findOneById($id); instead and it works fine.
When I tried to invistigate about the problem I was surprised since no documentation about the method Doctrine_Table::find() in the official website.
Any one knows what's the problem? is it deprecated?
BTW it's exists on the actual code! of the version (1.2.1).
more info about the database:
CREATE TABLE IF NOT EXISTS `country` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(64) NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `city` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(64) NOT NULL ,
`country_id` INT NOT NULL ,
PRIMARY KEY (`id`, `country_id`) ,
INDEX `fk_city_country` (`country_id` ASC) ,
CONSTRAINT `fk_city_country`
FOREIGN KEY (`country_id` )
REFERENCES `country` (`id` )
ON DELETE CASCADE
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_unicode_ci;
What's weird is that both Doctrine_Table::find(), and Doctrine_Table::findOneById() works fine on Country table!.
PS: I realize that Doctrine_Table::findOneById() is a __call() generated method. And that make me confused more, why the actual find() method can't behave as expected (is my expectation wrong or what)!
Oh my bad. I didnt see it earlier, shame on me =p
Your table has two primary keys (id and country_id), so the find method requires you to pass both parameters to the find method.
You could instead use the magic methods:
Doctrine::getTable('City')->findOneById(1)
As of v 1.2.1, Doctrine_Table::find() is NOT deprecated
You can check the official documentation on http://www.doctrine-project.org/documentation/manual/1_2/en/component-overview#table:finder-methods
As for the "invalid parameter number" error, it means you query has more or fewer parameters than expected, most often you used a token (?) and forgot to add the parameter to it
Doctrine_Query::create()
->from('User u')
->where('u.name = ?', 'Jonh')
->andWhere('u.is_active = ?')
The example i used have two tokens '?', but only one parameter 'jonh', it would throw the same error: "Invalid parameter number: number of bound variables does not match number of tokens"

Categories