I would like to create view on table for certain columns but looking option to change the datatype length while creating view.
Let say create table
create table test( a varchar(100))
as there option to change varchar 100 to 20 while creating view
create view R1 as select to_varchar(1, length(20)) ..
Thanks,
Yash
Yes, you could change data type, but be aware of possible truncation errors:
CREATE OR REPLACE VIEW R1
AS
SELECT LEFT(a, 20)::VARCHAR(20) AS a -- taking first 20 chars to avoid truncation
FROM test;
DESCRIBE VIEW R1;
Option 2:
CREATE OR REPLACE VIEW R1
AS
SELECT TRY_CAST(a, VARCHAR(20)) AS a -- string longer than 20 chars are casted as NULL
FROM test;
DESCRIBE VIEW R1;
Related
I have a computed column created with the following line:
alter table tbPedidos
add restricoes as (cast(case when restricaoLicenca = 1 or restricaoLote = 1 then 1 else 0 end as bit))
But, now I need to change this column for something like:
alter table tbPedidos
alter column restricoes as (cast(case when restricaoLicenca = 1 or restricaoLote = 1 or restricaoValor = 1 then 1 else 0 end as bit))
But it's not working. I'm trying to input another condition to the case statement, but it's not working.
Thanks a lot!
Something like this:
ALTER TABLE dbo.MyTable
DROP COLUMN OldComputedColumn
ALTER TABLE dbo.MyTable
ADD OldComputedColumn AS OtherColumn + 10
Source
If you're trying to change an existing column, you can't use ADD. Instead, try this:
alter table tbPedidos
alter column restricoes as
(cast(case when restricaoLicenca = 1 or restricaoLote = 1 or restricaoValor = 1
then 1 else 0 end as bit))
EDIT: The above is incorrect. When altering a computed column the only thing you can do is drop it and re-add it.
This is one of those situations where it can be easier and faster to just use the diagram feature of SQL Server Management Studio.
Create a new diagram, add your table, and choose to show the formula column in the diagram's table view.
Change the columns formula to an empty string ('') or something equally innocuous (probably such that you don't change the column's datatype).
Save the diagram (which should save the table).
Alter your function.
Put the function back in the formula for that column.
Save once again.
Doing it this way in SSMS will retain the ordering of the columns in your table, which a simple drop...add will not guarantee. This may be important to some.
Another thing that might be helpful to someone is how to modify a function that's a calculated column in a table (Following query is for SQL):
ALTER <table>
DROP COLUMN <column>
ALTER FUNCTION <function>
(
<parameters>
)
RETURNS <type>
BEGIN
...
END
ALTER <table>
ADD <column> as dbo.<function>(parameters)
Notes:
Parameters can be other columns from the table
You may not be able to run all these queries at once, I had trouble with this. Run them one at a time
SQL automatically populates calculated columns, so dropping and adding won't affect data (I was unaware of this)
My question is the same as this old one, but creating an in-memory table instead of a temp table:
Best way to create a temp table with same columns and type as a permanent table
I have tried this, because it is the accepted answer in the old question, but it does not work (I think it is because the table variable must be declared):
select top 0 *
into #mymemorytable
from myrealtable
It throws that exception:
Msg 102 Level 15 State 1 Line 2 Incorrect syntax near '#memorytable'.
I have also tried to declare the table variable as declare #mymemorytable as table();, but of course it throws an exception:
Msg 102 Level 15 State 1 Line 1 Incorrect syntax near ')'.
Is there any way to achieve it without declaring the table variable detailing all the fields and types? Which is the best way to get it?
Thank you
I think the most you can do is something like this:
CREATE TYPE dbo.MyTableType
AS TABLE
(
Column1 int
, Column2 int
)
GO
DECLARE #InMemTable dbo.MyTableType
;
INSERT INTO #InMemTable VALUES (1,1), (1,2), (2,3)
;
SELECT * from #InMemTable
;
There are no columns in your declaration of #table.
You need to enter the structure of "myrealtable".
If you want to skip that part you need to use a temporary table instad of a table value parameter.
Ie
SELECT *
INTO #table
FROM myrealtable
Alos, it's considered good practise to drop the temporary table once your done with it.
It's also considered bad practise to use SELECT * instead of listing all columns :)
For example, this is possible in Oracle. I wanted to know if snowflake has a similar concept.
CREATE TABLE Purchases
(
purchase_date calendar.date%type,
customer_nr customer.customer_nr%type,
purchase_amount numeric(10,2)
)
I'm afraid there's no way to do that right now. You can use system$typeof to check for a column type, but that can't be used in a create table statement.
The referenceability that you have in your example is not available. You can build a table by joining one or more tables and/or views together and build the column list with columns from any of the joins and any that you explicitly add to the list. The key is to join on 1 = 2 or FALSE
Example
CREATE OR REPLACE TEMP TABLE TMP_X
AS
SELECT A."name" AS NAME
,A."owner" AS OWNER
,B.STG_ARRAY
,NULL::NUMERIC(10,2) AS PURCHASE_AMOUNT
,NULL AS COMMENT
FROM TABLE_A A
JOIN TABLE_B B
ON 1 = 2
;
NAME - takes datatype from A."name" column
OWNER - takes datatype from A."owner" column
STG_ARRAY - takes datatype from B.STG_ARRAY column
PURCHASE_AMOUNT - takes the datatype explicitly specified NUMERIC(10,2)
COMMENT - no explicit datatype -- takes default datatype of VARCHAR(16777216)
I have a postgres table, with a column C which has type T. People will be using COPY to insert data into this table. However sometimes they try to insert a value for C that isn't of type T, however I have a postgres function which can convert the value to T.
I'm trying to write a BEFORE INSERT trigger on the table which will call this function on the data so that I can ensure that I get no insert type errors. However it doesn't appear to work, I'm getting errors when trying to insert the data, even with the trigger there.
Before I spend too much time investigating, I want to find out if this is possible. Can I use triggers in this way to change the type of incoming data?
I want this to run on postgresql 9.3, but I have noticed the error and non-functioning trigger on postgres 9.5.
As Patrick stated you have to specify a permissive target so that Postgres validation doesn't reject the data before you get a chance to manipulate it.
Another way without a second table, is to create a view on your base table that casts everything to varchar, and then have an INSTEAD OF trigger that populates the base table whenever an insert is tried on the view.
For example, the table tab1 below has an integer column. The view v_tab1 has a varchar instead so any insert will work for the view. The instead of trigger then checks to see if the entered value is numeric and if not uses a 0 instead.
create table tab1 (i1 int, v1 varchar);
create view v_tab1 as select cast(i1 as varchar) i1, v1 from tab1;
create or replace function v_tab1_insert_trgfun() returns trigger as
$$
declare
safe_i1 int;
begin
if new.i1 ~ '^([0-9]+)$' then
safe_i1 = new.i1::int;
else
safe_i1 = 0;
end if;
insert into tab1 (i1, v1) values (safe_i1, new.v1);
return new;
end;
$$
language plpgsql;
create trigger v_tab1_insert_trigger instead of insert on v_tab1 for each row execute procedure v_tab1_insert_trgfun();
Now the inserts will work regardless of the value
insert into v_tab1 values ('12','hello');
insert into v_tab1 values ('banana','world');
select * from tab1;
Giving
|i1 |v1 |
+-----+-----+
|12 |hello|
|0 |world|
Fiddle at: http://sqlfiddle.com/#!15/9af5ab/1
No, you can not use this approach. The reason is that the backend already populates a record with the values that are to be inserted into the table. That is in the form of the NEW parameter that is available in the trigger. So the error is thrown even before the trigger fires.
The same applies to rules, incidentally, so Kevin's suggestion in his comment won't work.
Probably your best solution is to create a staging table with "permissive" column data types (such as text) and then put a BEFORE INSERT trigger on that table that casts all column values to their correct type before inserting them in the final table. If that second insertion is successful you can even RETURN NULL from the insert so the row won't go into the table (not sure, though, what COPY thinks about that...). Those records that do end up in the table have some weird data in them and you can then deal with those rows manually.
I want to alter a table and add a column that is the sum of two other columns, and this column is auto computed when I add new data.
The syntax for a computed column specification is as follows:
column-name AS formula
If the column values are to be stored within the database, the PERSISTED keyword should be added to the syntax, as follows:
column-name AS formula PERSISTED
You didn't mention an example, but if you wanted to add the column "sumOfAAndB" to calculate the Sum of A and B, your syntax looks like
ALTER TABLE tblExample ADD sumOfAAndB AS A + B
Hope that helps.
Rather than adding this column to the table, I would recommend using a View to calculate the extra column, and read from that.
Here is a tutorial on how to create views here:
http://odetocode.com/Articles/299.aspx
Your view query would look something like:
SELECT
ColumnA, ColumnB, (ColumnA+ColumnB) as ColumnC
FROM
[TableName]
You can use a view, but you may want to use a PERSISTED computed value if you don't want to incur the cost of computing the value each time you access the view.
e.g.
CREATE TABLE T1 (
a INT,
b INT,
operator CHAR,
c AS CASE operator
WHEN '+' THEN a+b
WHEN '-' THEN a-b
ELSE a*b
END
PERSISTED
) ;
See the SQL docs assuming you're using SQL Server of course.
How to create computed column during creation of new table:
CREATE TABLE PRODUCT
(
WORKORDERID INT NULL,
ORDERQTY INT NULL,
[ORDERVOL] AS CAST
(
CASE WHEN ORDERQTY < 10 THEN 'SINGLE DIGIT' WHEN ORDERQTY >=10 AND ORDERQTY < 100 THEN 'DOUBLE DIGIT'
WHEN ORDERQTY >=100 AND ORDERQTY < 1000 THEN 'THREE DIGIT' ELSE 'SUPER LARGE' END AS NVARCHAR(100)
)
)
INSERT INTO PRODUCT VALUES (1,1),(2,-1),(3,11)
SELECT * FROM PRODUCT
UPDATE table_name SET total = mark1+mark2+mark3;
first think you can insert all the data into the table and then you can update the table like this form.
//i hop it's help to you