I have a polymorphic table, like so:
| id (Uuid, not null) | name (Text, nullable) | other_property (Bool, not null) |
and a check constraint like this:
other_property OR name IS NOT NULL
The idea behind this being that there are two "types" of objects in this table, one with a name and one without - and the reason I'm doing that is because I don't want to duplicate the relationship tables (i.e. "one_to_many_table_with_name", "one_to_many_table_without_name").
When creating a view like this:
CREATE VIEW with_name as
SELECT id, name FROM my_table WHERE other_property = False;
because the root table's name field is nullable, the view's name field is also nullable, even though I know it can't be null due to the check constraint.
is there a way to force postgres to make the column as NOT NULL?
Related
I would like to know if there is a way in sql to allow a column to have any value it wants for its attributes, but only one of them can be X value.
More specifically for easier explanations let's say i have:
create table status( current_status varchar(100), id integer )
what constraint should i add so i can only have up to one value of current_status='ACCEPTED' ?
EDIT:REMOVED mysql TAG
Partial index in Postgresql
create unique index index_accepted on status (current_status)
where current_status = 'ACCEPTED'
How can i create a table, that allows only to put data in NAME, if the data matches with the data that i want to be allowed in NAME. So like Bla1 or Bla2.
CREATE TABLE Table1 (
NAME VARCHAR(23)
NAME has to be one of them: ('Bla1', 'Bla2')
)
The best way to do it is probably to have a second table with all the allowed names in it, and making a FOREIGN KEY from the name field in your Table1 to the name field in that other table. That'll automatically fail any insert queries for which the name is not contained in the list of allowed names.
This has an advantage over things like ENUM and such in that it does not require you to rebuild your table (which is a very expensive operation) every time you want to allow another name and it also allows you to later add additional related info to each name by adding it to the other table.
Here's a great article on why using a foreign key is much better than using enums or other such checks in the table itself: http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/
Try this:
CREATE TABLE Table1 (
name VARCHAR(23) CHECK( name IN ('Bla1','Bla2') )
);
I have one table that has a Code and a Type property. I have another table which has a foo_id property. The foo_id is a Code of Type == foo so when creating a constraint between these two tables I need to match Code to foo_id and Type to the constant Foo.
Is there a way to do this? I don't want to add an Type column to my second table that is going to have the same value for every single row because that seems like a waste.
Table 1 Table 2
Code <--------------- Foo_id Foo_id maps to Code
Type <---"Foo" But Table 2 doesn't have a property
that maps to Type. But it should be
constant
I'm creating an association between Table 1 and Table 2 in my .edmx file. When I click on that association and then click on the Referential Constraint, I can see Code and Type for the principle key, but I only have foo_id I can use for the Dependent Property. So I want to specify that the constraint for Type should be a constant.
There are, of course, other values for Type other than Foo, but Table 2 in particular is only concerned with Foo types.
I can work around it by just doing something like:
var x = from i in Table2
select new { someT2Prop = i.Table2Prop,
someT1Prop = (from r in Table1 where r.Code == i.Foo_id
&& r.Type == "Foo" select r.Table1Prop).FirstOrDefault() };
But that's kind of messy. I'd like to just have a navigation property from Table 2 to Table 1, so I could do something like this:
var x = from i in Table2
select new { someT2Prop = i.Table2Prop,
someT1Prop = i.Table1.Table1Prop };
If I understand your question then:
Create a view:
SELECT Code
FROM [Table 1]
WHERE Type = "Foo"
Then constrain on Code values from this view.
I have a table in Oracle. This table has amongst others: EMPLOYEE_ID (NUMBER, Nullable, but number of NULLs is 0) and EMPLOYEE_NUMBER (VARCHAR2, Nullable, but number of NULLs is 0).
Now I create a view on this table:
CREATE OR REPLACE FORCE VIEW APPS.XXKE_L2E_EMPLOYEE
(
PERSON_ID,
EMPLOYEE_NUMBER,
...
)
AS
SELECT EMPLOYEE_ID,
EMPLOYEE_NUMBER,
...
FROM xxke.xxke_employees e
INNER JOIN xxke.xxke_organizations o ON e.organization_id = o.organization_id
INNER JOIN xxke.xxke_operating_units ou ON e.org_id = ou.org_id;
ALTER VIEW APPS.XXKE_L2E_EMPLOYEE
ADD CONSTRAINT XXKE_L2E_EMPLOYEE_V_PK
PRIMARY KEY(PERSON_ID) DISABLE;
How on earth is it possible that in that view PERSON_ID becomes Nullable (even when using NVL trick), but EMPLOYEE_NUMBER is NOT Nullable
QUESTION:
How can I make Oracle to create the view in a way, so the PERSON_ID column becomes NOT Nullable in the view? Or how can I make my WCF oData service query this view. Currently after updating the edmx file I get the following:
Errors: Oracle.ssdl(227,6) : error 0075: Key Part: 'PERSON_ID' for type XXKE_L2E_EMPLOYEE is not valid. All parts of the key must be non nullable.
the reason why it becomes nullable is when creating view query you used nvl on employee_id. The employee is not nullable in the query so that is why it is not. In a view, oracle makes the resulting column nullable. Views are not static but just a query. If you want to not have the issue you can create a materialized view of the table with the nvl pre applied in query then query will not have null possible selected. You can then do indexes and queries will be significantly faster.
If you want your column in the view to be non-nullable, then inner join with the table that contains this column as primary key and select (in this case) PERSON_ID from that table in the view definition. That resolves the problem.
My database holds template forms and real forms having values. Users will be able to create custom template forms with different types of fields. I will keep values in a separate table.
Forms table:
Id | Name | TemplateId
FormFields table:
Id | FormId | Name | ValueType (nvchar)
Values Table
FieldId | Value
When user designs a form it is saved into forms table having TemplateId NULL. Also FormFields table stores the fields that will be used for this form.
Later when user creates a real form using that template, the real values of this form (derieved from FormFields) will be stored in Values table.
Now, the value column in Values table seems to be sql_variant type. If I don't use sql_variant how can I solve this problem?
Ps: What about creating different tables for each kind of values? TableIntValues, TableBoolValues etc?
http://www.jotform.com/ can be a good sample for my project.
I would suggest using separate columns for the separate data types, along these lines:
FieldId | StringValue | IntegerValue | DateTimeValue
That way you can have queries run over the data sensibly, and also keep it type safe. You would obviously need logic to ensure that the data gets populated correctly, and a constraint to ensure only one column is populated and not all are NULL.