Avoid sql_variant but use what? - sql

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.

Related

How to modify languageid column in a SQLite FTS table?

In SQLite FTS tables there is a hidden languageid column that I want to make use of: I need to populate my FTS4 table with rows in two different languages, which I will then distinguish by languageid column.
I create my table with a command like this:
CREATE VIRTUAL TABLE `texts` USING FTS4(`text`, tokenize=unicode61, languageid=`lid`)
Now how can I INSERT a row with a specified languageid if it is a hidden column? Or is there some other way to specify the language used in a row?
So, I had to explicitly specify the languageid column like this (here lid is the name of languageid column):
INSERT INTO `texts` (`text`,`lid`) VALUES (?,?)
Sidenote: I used Python in IntelliJ IDEA for this and the IDE gave me a Unable to resolve column 'lid' error, but the code still worked.

Snowflake Reference Table

How to create a reference table in Snowflake that picks up the column name and the column value together as a result to be referenced in another SQL Query ?
Suppose on I have an Item Table ( as shown below - )
| ITEM_NAME|ORDER_TYPE | REGION|
|:--------|:----------:|------:|
| Godan | Return| North|
And I have a set of rules as mentioned below
If Item name is '%NAME% then YES
IF Region is 'NORTH' then NO etc
What would be the best possible way to create a reference table in Snowflake containing the results of these rules which can be later accessed by any other view in Snowflake(Column and Value together) or and ETL Tool ?

Trouble with uniqueidentifier column

I just started working with SQL Server and I have some troubles with adding values to a table with a column of type uniqueidentifier.
The table consists of:
ID (uniqueidentifier), CODE (nchar(5)), COUNTRY_CODE(nchar(2)), NAME(nchar30)
I tried adding values from Excel and CSV files, basically they look like this:
DEBE,DE,Berlin
I could not load it, always have some errors with this ID field.
When i try to add values manually like:
INSERT INTO [Portfolio].[dbo].[Regions](CODE, COUNTRY_CODE, NAME)
VALUES ('DEBE', 'DE', 'Berlin');
It says:
Cannot insert the value NULL into column 'ID', table
'Portfolio.dbo.Regions'; column does not allow nulls. INSERT fails.
Of course when I add an id column and a number, I get info that int is incompatible with uniqueidentifier.
I even tried creating a temp table (with id as an INT instead of uniqueidentifier) and copying values from it into this (without ID column, its supposed to generate automatically)
Only thing I can think of is that ID column is not creating values for it automatically and I don't know how to solve this. Can anyone help?
Uniqueidentifier is a special type you can use to generate GUID. Is 16 byte long and is not incremented automatically as the Identity columns. You need to use Convert or Cast clause in order to get the correct uniqueidentifier from a varchar, if it exceeds the 16bytes it will be truncated.
Use NewID() to generate a new uniqueidentifier.
Maybe this link can help you
As mentioned above, use NewID() to create an identifier.
When you are in the design mode for the table, NewID() can be placed in the 'Default Value or Binding' slot. This means that for any new record that you insert into the table (such as CODE, COUNTRY_CODE, NAME), a Unique Identifier will be created.
What I think you are looking for is an Identity field. The UniqueIdentifier field is used for storing GUID's.
Change the field type to int and then change it's Identity Specification to 'Yes".
The other solution would be to pass the ID field your own GUID from code.
Too late to answer, but it may help someone, go to you sql table design mode,
select your required table's attribute, here in detail tab (down to table) you'll see a property
RowGuid --> Yes (make sure to turn it to yes).
Cheers :)

sql - retain calculated result in calculated field

certain fields in our database contain calculated functions e.g.
select lastname + ', ' + firstname as fullname from contact where contact.id =$contact$
when viewing the field the correct data is shown (i assume this is because when you open the record, the calculation is executed). however, the data is not 'stored' to the field, and therefore is null until the record is opened. is it possible to 'store' the result to the field, making it possible to search the data?
many thanks
james
EDIT
it is not possible for me to create computed_columns using our software.
the above field is a text feild where either 1) a user can manual type in the required data or 2) the database can generate the answer for you (but only whilst you are looking at the record). i know that if I run the following:
Select * from contact where contact.id =$contact$ for xml auto
i only get lastname, firstname - so i know that the fullname field does not retain its information.
If you are using computed columns in sql server, the column is already searchable regardless of whether the calculation result is stored or not. However, if you would like to make it so that the calculation is not run each time you read the row, you can change that under row properties in your Modify Table GUI.
Use the PERSISTED key word when you create the column
From BOL:
PERSISTED
Specifies that the SQL Server Database Engine will physically store the computed values in the table, and update the values when any other columns on which the computed column depends are updated. Marking a computed column as PERSISTED lets you create an index on a computed column that is deterministic, but not precise. For more information, see Creating Indexes on Computed Columns. Any computed columns that are used as partitioning columns of a partitioned table must be explicitly marked PERSISTED. computed_column_expression must be deterministic when PERSISTED is specified.
This isn't the way computed columns work in SQL Server, so I suspect this is something your client application is doing. How are you looking at the data when the value is computed correctly? Does it work when you view the data in SSMS?
Take a look at http://msdn.microsoft.com/en-us/library/ms191250(v=SQL.90).aspx to see how to create computed columns properly.
eg.
create table TestTable
(a int,
b int,
c as a + b)
insert into TestTable (a,b)
values (1,2)
select * from TestTable
where c = 3
This query is based on the computed column and it returns the row that's been inserted.
You need to use the PERSISTED option on a column when you use CREATE TABLE e.g.
CREATE TABLE test (col_a INT, col_b INT, col_c AS col_A * col_B PERSISTED)

Query a union table with fields as columns

I'm not quite sure if this is possible, or falls into the category of pivot tables, but I figured I'd go to the pros to see.
I have three basic tables: Card, Property, and CardProperty. Since cards do not have the same properties, and often multiple values for the same property, I decided to use the union table approach to store data instead of having a really big column structure in my card table.
The property table is a basic keyword/value type table. So you have the keyword ATK and the value assigned to it. There is another property called SpecialType which a card can have multiple values for, such as "Sycnro" and "DARK"
What I'd like to do is create a view or stored procedure that gives me the Card Id, Card Name, and all the property keywords assigned to the card as columns and their values in the ResultSet for a card specified. So ideally I'd have a result set like:
ID NAME SPECIALTYPE
1 Red Dragon Archfiend Synchro
1 Red Dragon Archfiend DARK
1 Red Dragon Archfiend Effect
and I could tally my results that way.
I guess even slicker would be to simply concatenate the properties together based on their keyword, so I could generate a ResultSet like:
1 Red Dragon Archfiend Synchro/DARK/Effect
..but I don't know if that's feasible.
Help me stackoverflow Kenobi! You're my only hope.
Is this for SQL server?
If yes then
Concatenate Values From Multiple Rows Into One Column (2000)
Concatenate Values From Multiple Rows Into One Column Ordered (2005+)
Related but values are values are kept in separate columns and you have know your "special types" a head of time: SQL query to compare product sales by month
Otherwise I would do this with cursor in a stored procedure or preform the transformation in the business or presentation layer.
Stab at sql if you know all cases:
Select
ID,NAME
,Synchro+DARK+Effect -- add a some substring logic to trim any trailing /'s
from
(select
ID
,NAME
--may need to replace max() with min().
,MAX(CASE SPECIALTYPE WHEN "Synchro" THEN SPECIALTYPE +"/" ELSE "" END) Synchro
,MAX(CASE SPECIALTYPE WHEN "DARK" THEN SPECIALTYPE +"/" ELSE "" END) DARK
,MAX(CASE SPECIALTYPE WHEN "Effect" THEN SPECIALTYPE ELSE "" END) Effect
from
table
group by
ID
,NAME) sub1
Don't collapse by concatenation for storage of related records in your database. Its not exactly best practices.
What you're describing is a pivot table. Pivot tables are hard. I'd suggest avoiding them if at all possible.
Why not just read in your related rows and process them in memory? It doesn't sound like you're going to spend too many milliseconds doing this...
One option is to have Properties have a PropertyType, so:
table cards
integer ID | string name | ... (other properties common to all Cards)
table property_types
integer ID | string name | string format | ... (possibly validations)
table properties
integer ID | integer property_type_id | string name | string value
foreign key property_type_id references property_types.ID
table cards_properties
integer ID | integer card_id | integer property_id
foreign key card_id references cards.ID
foreign key property_id references propertiess.ID
That way, when you want to set a new property value, you can validate it by its type. One type could be "SpecialType" with an enumeration of values.
I do have a type/format for my properties table, that way I know how to cast/evaluate when I'm dealing with an integer value. I wasn't sure if it was pertinent to this issue or not.