I have a table with a column name of datatype varchar2. How can I use check constraint on name such that it will not accept NUMERIC VALUES AS WELL AS SPECIAL CHARACTERS in it?????
Assuming you are using ms sql
ALTER TABLE table
ADD
CONSTRAINT column_alpha_check
CHECK
(
field like '%[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]%'
)
Also
In SQL you can enhance function to do that
Related
When creating a database table in jupyter, we specify restrictions on data types in the columns of the table, but for some reason we can still add other data types. For example, the st_gr column should contain only numbers, but nothing will stop us from adding a line (code below) Why? How to fix?
%%sql sqlite://
CREATE TABLE students(
st_id INTEGER PRIMARY KEY AUTOINCREMENT,
fname VARCHAR(15) NOT NULL,
lname VARCHAR(15) NOT NULL,
st_gr NUMERIC
)
%%sql sqlite://
INSERT INTO students (fname, lname, st_gr) VALUES('Barack', 'Obama', 'text not num')
SQLite uses dynamic type system. Declared column type only indicates the preferred value type, unless the table is strict.
If you are using sqlite version > 3.37.0, look into using STRICT tables.
If not, perhaps check constraints? software verification? a different database?
I'm trying to create table with default primary key (not autoincrement), similar with oracle
fk_id varchar2(32) default sys_guid()
so table definition is
CREATE TABLE `t_table` (
`fk_id` TEXT DEFAULT 'select lower(hex(randomblob(16)))' UNIQUE,
`fv_name` TEXT,
PRIMARY KEY(`fk_id`)
);
and yes, i'm getting this select as string value while inserting.
so is there any solution without using triggers?
thank you.
Using 'select lower(hex(randomblob(16)))' is enclosing the subquery as a string/text literal and will work only once as UNIQUE has been specified (no need as making the column PRIMARY KEY implies UNIQUE) thus any subsequent inserts would fail.
Assuming that you want the DEFAULT value to be the result of the of lower(hex(randomblob(16)) then you cannot use a subquery as the value is then not considered as a CONSTANT.
For the purposes of the DEFAULT clause, an expression is considered
constant if it contains no sub-queries, column or table references,
bound parameters, or string literals enclosed in double-quotes instead
of single-quotes.SQL As Understood By SQLite - CREATE TABLE
Instead you could remove the select and just use the expression, which is then considered CONSTANT.
However, to do so, you need to adhere to
If the default value of a column is an expression in parentheses, then
the expression is evaluated once for each row inserted and the results
used in the new row. SQL As Understood By SQLite - CREATE TABLE
Thus you could use :-
CREATE TABLE IF NOT EXISTS `t_table` (
`fk_id` TEXT DEFAULT (lower(hex(randomblob(16)))) UNIQUE,
`fv_name` TEXT,
PRIMARY KEY(`fk_id`)
);
Of course should the value not be unique, which would be increasingly likely, then this would result in the row not being inserted.
I am trying to create a table in SQLite with blob type column (Content):
create table [Files]
(
Id int identity not null
constraint PK_File_Id primary key,
MimeType nvarchar (400) not null,
Content varbinary (max) null
constraint DF_File_Content default (0x),
);
However the following is not being accepted:
Content varbinary (max) null
constraint DF_File_Content default (0x),
Why?
"Max" is the name of a standard SQLite3 function, so is not available as part of a type name.
See the syntax reference for the CREATE TABLE statement and data types. A type name can include numbers in parentheses (which are ignored), but not the word “MAX”.
It looks like you're trying to use MS SQL Server syntax, and there are several errors in your code:
As mentioned above, (max) is not accepted as part of a type name. Since value lengths are unconstrained by default, simply omit it.
varbinary gives the column “numeric affinity”. While such a column can store a blob, you'll probably want to declare it as blob instead.
0x is not a valid blob literal. The correct way to write an empty blob is x''.
identity is called autoincrement. And in order to use it, the type name must be integer rather than int. The not null is redundant: If you try to insert a null value into such a column, you'll get the auto-incremented ROWID instead.
Note: If you simply need Id to have unique values at any given time and don't care if previously-deleted values get re-used, then you can simply declare the column as integer primary key, and inserting null will fill in the column with an unused integer. The autoincrement keyword prevents the re-use of ROWIDs over the lifetime of the database, more closely matching the semantics of MS SQL's identity keyword. See the discussion at the link above.
While it's syntactically legal to declare a name for a column constraint, it's not necessary.
Try this:
create table [Files]
(
Id integer primary key autoincrement,
MimeType nvarchar (400) not null,
Content blob null default (x'')
);
Note that this does not enforce a length limit on a MimeType column. If you need to, add the constraint check (length(MimeType) <= 400).
I'm working on a small SQLite database using the Unix command line sqlite3 command tool. My schema is:
sqlite> .schema
CREATE TABLE status (id text, date integer, status text, mode text);
Now I want to set the column 'mode' to the string "Status" for all entries. However, if I type this:
sqlite> UPDATE status SET mode="Status";
Instead of setting column 'mode' to the string "Status", it sets every entry to the value that is currently in the column 'status'. Instead, if I type the following it does the expected behavior:
sqlite> UPDATE status SET mode='Status';
Is this normal behavior?
This is also a FAQ :-
My WHERE clause expression column1="column1" does not work. It causes every row of the table to be returned, not just the rows where column1 has the value "column1".
Use single-quotes, not double-quotes, around string literals in SQL. This is what the SQL standard requires. Your WHERE clause expression should read: column1='column2'
SQL uses double-quotes around identifiers (column or table names) that contains special characters or which are keywords. So double-quotes are a way of escaping identifier names. Hence, when you say column1="column1" that is equivalent to column1=column1 which is obviously always true.
http://www.sqlite.org/faq.html#q24
Yes, that's normal in SQL.
Single quotes are used for string values; double quotes are used for identifiers (like table or column names).
(See the documentation.)
I collected some values to be looked up from a DB column inside a string variable and was trying to pass this as a parameter in the SQL StoredProcedure.
ALTER PROCEDURE [dbo].[InkDB]
(
#ser nvarchar(255),
#svt nvarchar(255)
)
AS
SELECT DISTINCT Details from tbData WHERE (Name IN #svt AND Address=#ser)
This gives me a syntax error near #svt message while trying to run the query.
From my webpage, the parameter has value something like ('PersonA', 'Person B', 'Person C') that is being passed. How do I use the IN statement in this case?
I would do it with XML. Could not find this solution in the duplicate question so I add it here.
Your SP could look like this:
alter procedure InkDB
#ser nvarchar(255),
#svt xml
as
declare #T table
(
Name nvarchar(50)
)
insert into #T
select T.N.value('.', 'nvarchar(50)')
from #svt.nodes('/N') as T(N)
select distinct Details
from tbData
where Name in (select Name from #T) and
Address=#ser
And you would call it like this.
exec InkDB '', '<N>PersonA</N><N>PersonB</N>'
Dynamic Query
Alter procedure test
(
#ser nvarchar(255),
#svt nvarchar(255)
)
AS
BEGIN
declare #sql nvarchar(Max)
Set #sql='SELECT DISTINCT semester_code from mst_paper WHERE course_code IN ('+#svt+') AND branch_code='+#ser+''
exec sp_executesql #sql
END
Its a common mistake - you are passing a single value (expression) of type string to IN operator but IN expects a comma delimited list of values (expressions) and not a single string variable.
What you need to do here is to have a function that would split the given parameter into a multiple values based on given delimiter and then use that list with IN keyword. For example,
SELECT DISTINCT Details from tbData WHERE Name IN (SELECT Val FROM dbo.efn_Split(#svt, ',')) AND Address=#ser
where efn_Split is a table value function that will split comma-separated values into a table. See these various SO questions for implementation of such function:
Split function equivalent in T-SQL?
How to split string using delimiter char using T-SQL?
Yet another alternative is to construct the SQL statement and execute with sp_executesql.
IN needs to be as follows:
... IN (#param1, #param2, ...)
So, you should do:
SELECT DISTINCT Details from tbData WHERE Name IN (#svt) AND Address=#ser
Update:
The alter procedure statement you provided in your question is syntactically incorrect. My answer provides the correct syntax for writing the statement and it compiles.
Reading your question over again, I see you have in fact have two issues. The first was a syntax error and the second passing in a comma delimited list in a single parameter.
The answer is you simply cannot provided a comma delimited list of values at runtime into a single string type parameter that is used in the IN (...) clause. Now, on this second point, I would argue that this is not a good design/programming approach to the problem, but it can be done using dynamic SQL or parsing out each value from the string parameter, store them into a temp table then revise your query to join to that, or use a (or use a table valued function and store the parsed items there, where it can be queried from.
Below is the corrected syntax for your code, but it would not solve the second aspect of passing in a string containing a comma delimited list of values. That could be solved as I described above.
For the syntax error, first, you can create a dummy table to test your code. Note, a typical database table should have a primary key. This is strictly a dummy table to test the statement:
CREATE TABLE TbData(
Name nvarchar(255),
Details nvarchar(255),
Address nvarchar(255)
);
Then, you can create the initial stored procedure:
CREATE PROCEDURE Test
(
#ser nvarchar(255),
#svt nvarchar(255)
)
AS
BEGIN
SELECT DISTINCT Details FROM tbData WHERE Name IN (#ser) AND Address = #svt
END
And finally, execute the alter stored procedure statement you had asked about:
ALTER PROCEDURE Test
(
#ser nvarchar(255),
#svt nvarchar(255)
)
AS
BEGIN
SELECT DISTINCT Details FROM tbData WHERE Name IN (#ser) AND Address = #svt
END