Is it possible to set UserDefinedTableType column default value? - tsql

I have created my own TableType, is it possible to set a date column default in order to not call GetDate() within every insert?

It's quite straightforward, as in case of regular tables, but you can not assign a name to that constraint:
CREATE TYPE TestType AS TABLE
( ID INT,
CreatedDate DATETIME DEFAULT(GETDATE())
)

Related

Computed table column with MAX value between rows containing a shared value

I have the following table
CREATE TABLE T2
( ID_T2 integer NOT NULL PRIMARY KEY,
FK_T1 integer, <--- foreign key to T1(Table1)
FK_DATE date, <--- foreign key to T1(Table1)
T2_DATE date, <--- user input field
T2_MAX_DIFF COMPUTED BY ( (SELECT DATEDIFF (day, MAX(T2_DATE), CURRENT_DATE) FROM T2 GROUP BY FK_T1) )
);
I want T2_MAX_DIFF to display the number of days since last input across all similar entries with a common FK_T1.
It does work, but if another FK_T1 values is added to the table, I'm getting an error about "multiple rows in singleton select".
I'm assuming that I need some sort of WHERE FK_T1 = FK_T1 of corresponding row. Is it possible to add this? I'm using Firebird 3.0.7 with flamerobin.
The error "multiple rows in singleton select" means that a query that should provide a single scalar value produced multiple rows. And that is not unexpected for a query with GROUP BY FK_T1, as it will produce a row per FK_T1 value.
To fix this, you need to use a correlated sub-query by doing the following:
Alias the table in the subquery to disambiguate it from the table itself
Add a where clause, making sure to use the aliased table (e.g. src, and src.FK_T1), and explicitly reference the table itself for the other side of the comparison (e.g. T2.FK_T1)
(optional) remove the GROUP BY clause because it is not necessary given the WHERE clause. However, leaving the GROUP BY in place may uncover certain types of errors.
The resulting subquery then becomes:
(SELECT DATEDIFF (day, MAX(src.T2_DATE), CURRENT_DATE)
FROM T2 src
WHERE src.FK_T1 = T2.FK_T1
GROUP BY src.FK_T1)
Notice the alias src for the table referenced in the subquery, the use of src.FK_T1 in the condition, and the explicit use of the table in T2.FK_T1 to reference the column of the current row of the table itself. If you'd use src.FK_T1 = FK_T1, it would compare with the FK_T1 column of src (as if you'd used src.FK_T1 = src.FK_T2), so that would always be true.
CREATE TABLE T2
( ID_T2 integer NOT NULL PRIMARY KEY,
FK_T1 integer,
FK_DATE date,
T2_DATE date,
T2_MAX_DIFF COMPUTED BY ( (
SELECT DATEDIFF (day, MAX(src.T2_DATE), CURRENT_DATE)
FROM T2 src
WHERE src.FK_T1 = T2.FK_T1
GROUP BY src.FK_T1) )
);

CREATE FUNCTION failed because a column name is not specified for column 1. error for the Multiple parameter of function

Wanted to create the multiple parameter of function but it gives me this error:
CREATE FUNCTION failed because a column name is not specified for
column 1.
Code below:
create function dmt.Impacted(
#nameOfColumn varchar , #nameOfParam varchar)
returns table
as
return
(select
case when '['+#nameOfColumn+']' is null or len(rtrim('['+#nameOfColumn+']')) = 0
then Convert(nvarchar(2),0)
else
#nameOfParam end from employee) ;
As the error message clearly said, the column in the returned result need a name. Either give it an alias in the SELECT like
SELECT CASE
...
END a_column_name
...
or define it in the declaration of the return type as in
...
RETURNS TABLE
(a_column_name nvarchar(max)
...
As you can see in the second form you have to specify a data type. As your current code doesn't make much sense now I cannot figure out what is the right one there. You'd need to amend it.
Note, that len(rtrim('['+#nameOfColumn+']')) = 0 is never true as len(rtrim('['+#nameOfColumn+']')) is either NULL, when #nameOfColumn is NULL or at least 2 because of the added brackets.
If #nameOfColumn is supposed to be a column name you shouldn't use varchar (especially without a length specified for it) but sysname which is a special type for object names.
Either way you should define a length for #nameOfColumn and #nameOfParam as just varchar without any length means varchar(1), which is probably not what you want. And maybe instead of varchar you want nvarchar.
You may also want to look into quotename().
Define name of column in SELECT statement :
(select case when '['+#nameOfColumn+']' is null or
len(rtrim('['+#nameOfColumn+']')) = 0
then Convert(nvarchar(2),0)
else #nameOfParam
end as name_column -- define column name
from employee)
Also, your function parameter has no data length, by default it will accept only 1 character #nameOfColumn varchar , #nameOfParam varchar & rest will trim.

Conversion failure varchar to int on a column cast as int

I've created a view called vReceivedEmail which includes a varchar column called RowPrimaryKeyValue. This column usually stores primary key id values, such as 567781, but every now and then has the descriptive text 'Ad hoc message'.
I've set the view up so that it only shows records that would hold the primary key values and then CAST the column as int.
SELECT CAST(Email.RowPrimaryKeyValue as int) as DetailID
FROM MessageStore.dbo.Email Email
WHERE ISNUMERIC(Email.RowPrimaryKeyValue) = 1
When I test the view, I only get records with the primary key values I expected, and when I look at the column listing for the view in the object explorer, the column is saved at the int data type.
I've then tried to apply the following WHERE clause in a separate query, referencing my saved view:
SELECT PotAcc.DetailID
FROM PotentialAccounts PotAcc
WHERE PotAcc.DetailID NOT IN (
SELECT RecEmail.DetailID
FROM vReceivedEmail RecEmail
)
...but I'm returning the following error:
Conversion failed when converting the varchar value 'Ad hoc message'
to data type int.
'Ad hoc message' is data from the column I filtered and converted to int, but I don't know how it's managing to trip up on this since the view explcitly filters this out and converts the column to int.
Since you are on SQL Server 2012, how about using try_convert(int,RowPrimaryKeyValue) is not null instead of isnumeric()?
Your view would look like so:
select try_convert(int, RowPrimaryKeyValue) as DetailID
from MessageStore.dbo.Email Email
where try_convert(int, RowPrimaryKeyValue) is not null
In SQL Server 2012 and up: each of these will return null when the conversion fails instead of an error.
try_convert(datatype,val)
try_cast(val as datatype)
try_parse(val as datatype [using culture])
Why doesn’t isnumeric() work correctly? (SQL Spackle)
Isnumeric() can be deceiving... however I'm betting this is due to SQL Server optimization. Though your view works, that doesn't mean the outer query guarantees that only INT is returned. Instead of using a view... use a CTE and try it. And since you are on 2012, this can all be avoided how SqlZim explained above.
WITH CTE AS(
SELECT CAST(Email.RowPrimaryKeyValue as int) as DetailID
FROM MessageStore.dbo.Email Email
WHERE ISNUMERIC(Email.RowPrimaryKeyValue) = 1)
SELECT PotAcc.DetailID
FROM PotentialAccounts PotAcc
WHERE PotAcc.DetailID NOT IN (
SELECT RecEmail.DetailID
FROM CTE RecEmail
)

cakePHP find() returns field name instead of just the column values

I'm trying to retrieve data from my database using the find() method.
But when I use find('all') it returns the column value and column name together, like this: { "date_1": "2015-25-12"}, of course, I want only the values from the column.
If I use find('list'), it comes back empty.
This is how I'm trying to retrieve my data:
$date1 = $this->Stocks->find('all', ['fields' => ['Stocks.date_1'], 'conditions' => ['Stocks.families_id' => $id]]);
This is my table:
CREATE TABLE stocks
(
families_id integer,
date_1 date NOT NULL,
date_2 date,
created timestamp without time zone,
modified timestamp without time zone,
id serial NOT NULL,
CONSTRAINT stocks_pkey PRIMARY KEY (id)
)
Everything else is working fine, but this one part.
I'm using PostgreSQL.
Although you problem was related to displayField.
To select a single column or a set of columns you can do like this
$date1 = $this->Stocks->find()
->select(['date_1'])
->where(['families_id' => $id]);

How to create a PostgreSQL column that is a set of enum values?

I like that I can create new enum types in PostgreSQL. But what if I want a column value that is a set of enum values. Do I need to implement that manually with an integer column type and bitwise operators, or is there a way to keep using the enums by name?
CREATE TYPE foo AS ENUM ('none', 'loud', 'bright', 'cheap')
CREATE TABLE t (
id serial,
properties [set of foo?]
)
...
SELECT * FROM t;
1 loud
2 loud, cheap
3 bright
4 none
...
You can use an array:
CREATE TYPE foo AS ENUM ('none', 'loud', 'bright', 'cheap');
CREATE TABLE t (
id serial,
properties foo[]
);