hide a column from table in MS SQL Server - sql

Can anyone please share the steps to hide the particular column from the table in SQL Server 2012 as I don't want to delete that column
By hide I mean that whenever I use the select query against that particular table it should never show me that column.
Is it possible?
I need to make the column as hidden irrespective of any user login and whatever query i use
3rd party edit
Based on the comment But the problem is whenever i open the table in sql i dont want to see that particular column i assume that the question is:
How can i configure ssms so that opening a table definition inside sql management studio to only show the columns the connected user has select right to?
The screenshot below shows all columns of the table Employee despite the fact that the login StackoverIntern has no select rights to the columns SSN, Salary

Late post but I think its worth to share
Earlier to SQLSERVER-2016 there was no any option to hide few columns from table when selecting *, however SQLSERVER-2016 come up with HIDDEN keyword by which you can now set columns hidden from Select * which you don't want to show and want only for some background process of your business logic.
The HIDDEN property is optional and will hide these columns
from a standard SELECT statement for backward compatibility with our
application and queries. You cannot apply the HIDDEN property to an existing column
.
you can alter existing table as well lets take an example of existing table
ALTER TABLE [dbo].[Account] ALTER COLUMN [StartDate] ADD HIDDEN;
ALTER TABLE [dbo].[Account] ALTER COLUMN [EndDate] ADD HIDDEN;
You can check this concept used more often in Temporal table
you can find more on this in below Temporal Table

You can use column level permissions so that targeted users cannot select on that column. However, this will not "hide" the column in the case of doing a SELECT * or SELECT SpecialColumn. Instead, it will fail the query, resulting in an error.
An alternative to allow easier queries, you can make a View that does not include this column:
create view MyTableEx As
SELECT Every, Other, Column
FROM MyTable
Then only grant SELECT permissions to the View, rather than the table, for certain users. However, this is still problematic for an application, which now has to know whether it should select from the Table or the View.
When it comes down to it, column level permissions are kind of an unnatural thing to do in a database.

If you do not want the column to show, then you should not include it in you select statement. It is also more efficient to not use an asterisk (*) in your select statement.
See this post for more info in the performance issue:
Performance issue in using SELECT *?

Related

SQL query change column name

I'm working on some current, and archived SQLite databases.
In current versions, a column is named message, but in the archived versions it's named message_id.
The query I'm running is pretty lengthy/complex, and it's just this one column that's changed. Is there any way I can do some kind of CASE EXISTS style query to do this, or am I just going to have to write a separate query?
I would suggest writing a view to access the historical data:
create view v_message_history
select message as message_id, . . .
from message_archive;
Then you can use the view and the two columns have the same name.
You could also use alter table to rename the column in either the history or current table. I am guessing, though, that you don't want to do that because it might break existing code.

Insert & Delete from SQL best practice

I have a database with 2 tables: CurrentTickets & ClosedTickets. When a user creates a ticket via web application, a new row is created. When the user closes a ticket, the row from currenttickets is inserted into ClosedTickets and then deleted from CurrentTickets. If a user reopens a ticket, the same thing happens, only in reverse.
The catch is that one of the columns being copied back to CurrentTickets is the PK column (TicketID)that idendity is set to ON.
I know I can set the IDENTITY_INSERT to ON but as I understand it, this is generally frowned upon. I'm assuming that my database is a bit poorly designed. Is there a way for me to accomplish what I need without using IDENTITY_INSERT? How would I keep the TicketID column autoincremented without making it an identity column? I figure I could add another column RowID and make that the PK but I still want the TicketID column to autoincrement if possible but still not be considered an Idendity column.
This just seems like bad design with 2 tables. Why not just have a single tickets table that stores all tickets. Then add a column called IsClosed, which is false by default. Once a ticket is closed you simply update the value to true and you don't have to do any copying to and from other tables.
All of your code around this part of your application will be much simpler and easier to maintain with a single table for tickets.
Simple answer is DO NOT make an Identity column if you want your influence on the next Id generated in that column.
Also I think you have a really poor schema, Rather than having two tables just add another column in your CurrentTickets table, something like Open BIT and set its value to 1 by default and change the value to 0 when client closes the Ticket.
And you can Turn it On/Off as many time as client changes his mind, with having to go through all the trouble of Insert Identity and managing a whole separate table.
Update
Since now you have mentioned its SQL Server 2014, you have access to something called Sequence Object.
You define the object once and then every time you want a sequential number from it you just select next value from it, it is kind of hybrid of an Identity Column and having a simple INT column.
To achieve this in latest versions of SQL Server use OUTPUT clause (definition on MSDN).
OUTPUT clause used with a table variable:
declare #MyTableVar (...)
DELETE FROM dbo.CurrentTickets
OUTPUT DELETED.* INTO #MyTableVar
WHERE <...>;
INSERT INTO ClosedTicket
Select * from #MyTableVar
Second table should have ID column, but without IDENTITY property. It is enforced by the other table.

How to delete a duplicate record without using primary key

I went for an interview today where they give me technical test on sql. One of them was how to delete duplicate records without a primary key.
For one I can't imagine a table without a primary key. Yes I have read the existing threads on this. Say this happened and needed to be fixed Now. Couldn't I just add to the end of the table a automatically incrementing id then use that to delete the duplicate record?
Can anyone think of a reason why that won't work? I tried it on a simple database I created and I can't see any problems
You've got a couple of options here.
If they don't mind you dropping the table you could SELECT DISTINCT * from the table in question and then INSERT this into a new table, DROPping the old table as you go. This obviously won't be usable in a Production database but can be useful for where someone has mucked up a routine that's populating a data warehouse for example.
Alternatively you could effectively create a temporary index by using the row number as per this answer. That answer shows you how to use the built in row_number() function in SQL server but could be replicated in other RDBMS' (not sure which but MySQL certainly) by declaring a variable called #row_num or equivalent and then using it in your SELECT statement as:
SET #row_num=0;
SELECT #row_num:=#row_num+1 AS row_num, [REMAINING COLUMNS GO HERE]
One of possible options how to do this:
select distinct rows from your table(you can achieve this using group by all columns)
insert result into new table
drop first table
alter second table to name of first one
But this is not always possible in production

general issue about creating views

I have got a rather basic question but I could not find a confirmation about it online. When you create a view like the one below
create view report AS
select employee_id
from employees
It will store the data in a virtual table. That's ok. But when you add additional employee ids AFTER you have created the view will they be displayed when you run the view again? Cuz what I need is basically some view that will display the latest records I have added in the tables. Is that possible?
Short answer is Yes, it will update....
Ok, so Views don't quite "store" data, they just present data in a different format or select certain columns from a table to create your own "view" of the data.
If you are just looking to find the most recent employee ids through a view, I would recommend adding a column with a created or modified date field defaulting to the date entered. Then have your table do an Order By the datefield descending and select only top few rows so you only get recent records. The way to do this is slightly different depending on if you are using SQL, Oracle, or MySQL.

How to restrict SQL columns based on id of requester?

In my application a requester has permission to query only certain columns. The columns may differ between requesters. The where clause changes between requests so that the rows returned change with each query. What is the best way to handle this access control? Should I use an array to store permitted columns and then do the check in my application?
I'm on PostgreSQL 9.x
Example:
We have medical professionals that can access records of patients but not all medical professionals should be able to access all information. They try to request arbitrary information about any patient (which have a uid) but we should enforce access controls.
So say the info is name, date of birth, blood type and illness
Doctor A has permission for all fields
Doctor B can see everything except blood type
Administrator can only see name and date of birth
Hematologist can only see blood type
To implement option 2, I would have a column permissions table something like the following:
CREATE TABLE ColumnPerms
(
user_or_role Varchar(50),
table_name Varchar(50),
column_name Varchar(50),
)
CREATE INDEX ix_Columnperms(user_or_role, table_name)
The *table_name* column is to allow this functionality to be implemented on more than just a single table in your app: if it's unnecessary, don't use it. You could adopt the convention that role names start with a '#' character, to ensure that there is no collision with user names.
Now, when you build your dynamic query, you can do something like
SELECT column_name
FROM ColumnPerms
WHERE user_or_role = '#manager'
AND table = 'Payroll'
AND column_name IN ('first_name', 'last_name', 'hire_date', 'base_salary', 'bonus')
(the IN clause should include EVERY column potentially to be returned).
The result of this query is a list of the column names that user is allowed to see. Just iterate through it to build your column list when constructing the dynamic SQL.
There are two approaches you could take:
Use Postgres to enforce the security using column level permissions for each user (or user role). Look at the syntax for GRANT here: http://www.postgresql.org/docs/current/static/sql-grant.html
Build dynamic sql statements limiting what rows may be returned for each user. This could become pretty tedious if there are many users, or many different column combinations. You'll probably want to keep a table of user ids, and "selectable" table, column names for building the query statement. If you want this generalized to many different queries, you could either build them on top of a table-returning function that does the column filtering, or revert to option 1.
For option 1, make sure that columns used in the join are selectable...