Copying the values from specific columns from an SQL table to another table - sql

I have two Tables: Users and Permission. They share 2 columns with the same name, so I need to copy values of those 2 columns from 'Users' to 'Permission'. However, since there is a third column on Permission that cannot go blank, it needs to be filled with the value '0' by default.
See the diagram for further understanding:
What SQL command should I use to perform this feat?
Thanks!

insert into permission( userid, login, permission )
select UserId, login, 0 from users

Related

Is there a way to give a user access to different columns on different rows of a table in PostgreSQL?

Is there a way to give a PostgreSQL user access to a different columns on different rows of a table? For example in the following table, is there some combination of GRANT or POLICY or ??? that would only allow the user to view the "allowed" cells?
CREATE TABLE my_table (
id INT,
col_a TEXT,
col_b TEXT
);
INSERT INTO my_table VALUES
(1, 'allowed', 'allowed'),
(2, 'allowed', 'forbidden')
;
I think it can be done by splitting the columns in to different tables, but is it possible with only a single table?
One possible solution suggested by O. Jones - use a view:
CREATE OR REPLACE VIEW my_secure_view AS
SELECT
id,
col_a,
CASE WHEN id = 1 THEN col_b ELSE NULL END AS col_b
FROM my_table;
GRANT SELECT ON my_secure_view TO whatever_user;
REVOKE SELECT ON my_table FROM whatever_user;
Is there a better way?
You can do this by creating a VIEW containing the rows and columns you allow your user to see, then granting the user SELECT access to the view but not the underlying table.
For example
CREATE OR REPLACE VIEW my_secure_view AS
SELECT allowedcol1, allowedcol2
FROM my_table
WHERE col_b <> 'forbidden';
GRANT SELECT ON my_secure_view TO whatever_user;
REVOKE SELECT ON my_table TO whatever_user;
You can also, if you wish, write stored procedures and grant access to them to the users you choose, while revoking access to the underlying tables.

how to copy specifc data in one user table to another user table

I need transfer specific data’s from one user table to another user table .I tried below code it worked but copied all the data’s but i need only specific datas to be copied
Insert into sys.book (select * from syste.mytable);
You have to put a WHERE clause on the SELECT to say what values you want:
INSERT INTO sys.book
SELECT * FROM syste.mytable
WHERE column1 = valueThatYouWantInTableBook

using insert into to append to existing table in a remote database

my goal is to select items from a table and append those items into another table located on a remote database on the same server. All columns in both tables match up and are identical. In this case,
I have the tsql:
INSERT INTO db1.dbo.tblitems
SELECT *
FROM db2.dbo.tblitems i2
WHERE i2 = 'import'
i get an error saying:
An explicit value for the identity column in table 'db1.dbo.tblitems' can only be specified when a column list is used and IDENTITY_INSERT is ON.
any ideas why this doesn't work?
thanks in advance
Sounds like there is an identity column in the table. An identity column is a column that is made up of values generated by the database. For example:
create table #TestTable (id int identity, name varchar(50))
insert into #TestTable select 1, 'Will Smith'
This gives the identity column error. You can avoid that in two ways: the first is not to insert the identity column, like:
insert into #TestTable (name) select 'Will Smith'
The second is to use set identity_insert (requires admin privileges):
set identity_insert #TestTable on
insert into #TestTable (id, name) select 1, 'Will Smith'
set identity_insert #TestTable off
In both cases, you have to specify the column list.
I agree with Andomar but a further consideration...
Have you considered the effects of merging these two data sets?
Say I had two identical tables in two databases with this data:
Id Name
1 Bill
2 Bob
3 Bert
Id Name
3 Jenny
4 Joan
5 Jackie
Option 1 of Andomar's would give the girls new IDs. If that ID has been used as a primary key in the table and other tables referenced it as a foreign key then this will break the referential integrity (you will have records pointing to the wrong place).
Option 2 would fall over if there is a unique index on the ID column, which quite likely if it is being used as a key. This is because the two ID values for Bert and Jenny are not unique.
So while Andomar is right in that it will fix the identity insert problem, it doesn't address the issue of why there were identity columns in the first place.
p.s. if this is an issue ask for a solution in a new question.
This might be an issue of permissions. As the server the query is running on cannot determine if the connected user has the permission to insert the data into the destination server/table, it just might not be possible.

Complicated/Simple SQL Insert: adding multiple rows

I have a table connecting principals to their roles. I have come upon a situation where I need to add a role for each user. I have a statement SELECT id FROM principals which grabs a list of all the principals. What I want to create is something like the following:
INSERT INTO role_principal(principal_id,role_id)
VALUES(SELECT id FROM principals, '1');
so for each principal, it creates a new record with a role_id=1. I have very little SQL experience, so I dont know if I can do this as simply as I would like to or if there is some sort of loop feature in SQL that I could use.
Also, this is for a mySQL db (if that matters)
Use VALUES keyword if you want to insert values directly. Omit it to use any SELECT (where column count and type matches) to get the values from.
INSERT INTO role_principal(principal_id,role_id)
(SELECT id, 1 FROM principals);
To avoid duplicates is useful to add a subquery :
INSERT INTO role_principal(principal_id,role_id)
(SELECT id, 1 FROM principals p
WHERE NOT EXISTS
(SELECT * FROM role_principal rp WHERE rp.principal_id=p.id AND role_id=1)
)

How do I make one user see a different table with same name

Goal: When everybody else does SELECT * FROM mytable they see one version of the table. But when a specific user does SELECT * FROM mytable they see another version of the table.
I think I'm like halfway there with creating a new role and putting the single user in it. Then creating a copy of the default table with SELECT * INTO newrole.mytable FROM dbo.mytable. But when the user does SELECT * FROM mytable they still see the dbo.mytable. How do I get them to default to the newrole.mytable? I still need them to see all the other dbo tables just not this one.
Create a new schema, and a duplicate table (or view onto dbo.table if that's what you want) in it - eg., otheruser.table. Then, set the user's login to default to that schema:
USE atest
GO
CREATE ROLE [arole]
GO
CREATE SCHEMA [aschema] AUTHORIZATION [arole]
GO
CREATE USER [auser] FOR LOGIN [modify_user] WITH DEFAULT_SCHEMA = aschema
GO
EXEC sp_addrolemember 'arole', 'auser'
GO
CREATE TABLE dbo.atable ( col1 int )
GO
CREATE TABLE aschema.atable (col2 varchar(10))
GO
INSERT INTO dbo.atable( col1 ) VALUES( 1 )
GO
INSERT INTO aschema.atable( col2 ) VALUES( 'One' )
GO
PRINT 'dbo'
SELECT * FROM atable
GO
EXECUTE AS USER = 'auser'
GO
PRINT 'aschema'
SELECT * FROM atable
GO
REVERT
GO
I don't know if this may help but you may be able to make a view of a different table with the same name, here is an excerpt from http://www.w3schools.com/SQl/sql_view.asp:
In SQL, a view is a virtual table based on the result-set of an SQL statement.
A view contains rows and columns, just like a real table. The fields in a view are fields from one or more real tables in the database.
You can add SQL functions, WHERE, and JOIN statements to a view and present the data as if the data were coming from one single table.
I use Postgres primarily, so YMMV, but in postgres you need to
1) Create the new schema, preferably owned by the new role, and put the table in it
2) Set the search_path variable to include that schema BEFORE the other one.
Hope it helps.
This is a very bad idea. I'm not sure why people try all these crazy methods to improve security but it's just plain counter productive.
Ultimately every security system comes down to some line like the following if(User.HasAccessTo(object)). In fact, if you've designed a well thought out security system that's almost exactly how it should work. The more disjointed your authentication checks, the more likely you'll make a mistake. If only some users have access to certain record information you should add a flag to those records and verify access based on that.