EF or SQL Server - Computed / Continous Column - sql-server

I'm not sure how to do this and where it should be implemented.
I have a table with columns: ID, TypeID, AIndex. Both the ID and TypeID are supplied when creating a new record. The AIndex is a continuous column based on both IDs.
To illustrate here an example:
ID TypeID Aindex
---------------------
1 1 1
1 1 2
1 2 1
1 3 1
2 1 1
2 1 2

The big question is:
They are lot of people writing to this table at a time?
When you compute Aindex column from previous database data, some thing like max( Aindex ) + 1 the risk is to induce locks.
If only few inserts are made in table you can write increment code in your favorite layer, EF or DB. But if your table has high write ratio you should search for a alternate technique like counters table or something else. You can keep this counters table with EF if you want.

Related

Extend row-level security to a bridging table

I am working on row level security in my database. I have two tables. Row based security is implemented on data_table and only returns rows that the user can see.
data_table:
data_id name role
-----------------------------
1 test USER
2 another ADMIN
3 yep USER
type_table:
type_id name
-----------------
1 this
2 is
3 a
4 type
EXECUTE AS USER = 'USER';
SELECT * FROM data_table;
returns rows 1 and 3 only. If you execute as ADMIN, all of the rows are returned. This is working properly in my database.
However, my issue is my bridging table.
data_type_table:
data_type_id data_id type_id
1 1 2
2 1 3
3 2 1
4 2 2
5 3 1
6 3 4
As of right now
EXECUTE AS USER = 'USER';
SELECT COUNT(data_type_id) FROM data_type_table;
returns 6 because it's looking at all 6 rows in the table. I'm trying to set it up in such a way that user USER will only see rows in data_type_table which are referencing rows where data_table.role = 'USER' (this means that the select count query would return 4). What would be the simplest way to implement something like this?
My data_table will more than likely contain hundreds of thousands of rows. Efficiency could become a problem here.

How to configure a table column in TSQL that works as a sequence depending on the values of another two columns?

I have a table that looks like this:
ID A B Count
-----------------
1 abc 0 1
2 abc 0 2
3 abc 1 1
4 xyz 1 1
5 xyz 1 2
6 xyz 1 3
7 abc 1 2
8 abc 0 3
The "Count" column is incremented by one in the next insertion depending on the value of fields "A" and "B". so for example, if the next record I want to insert is:
ID A B Count
-----------------
abc 0
The value of count will be 4.
I have been trying to find documentation about this, but I'm still quite lost in the MS SQL world! There must be a way to configure the "Count" column as a sequence dependent on the other two columns. My alternative would be to select all the records with A=abc and B=0, get the maximum "Count", and do +1 in the latest one, but I suspect there must be another way related to properly defining the Count column when creating the table.
The first question is: Why do you need this?
There is ROW_NUMBER() which will - provided the correct PARTITION BY in the OVER() clause - do this for you:
DECLARE #tbl TABLE(ID INT,A VARCHAR(10),B INT);
INSERT INTO #tbl VALUES
(1,'abc',0)
,(2,'abc',0)
,(3,'abc',1)
,(4,'xyz',1)
,(5,'xyz',1)
,(6,'xyz',1)
,(7,'abc',1)
,(8,'abc',0);
SELECT *
,ROW_NUMBER() OVER(PARTITION BY A,B ORDER BY ID)
FROM #tbl
ORDER BY ID;
The problem is: What happens if a row is changed or deleted?
If you write this values into a persistant column and one row is removed physically, you'll have a gap. Okay, one can live with this... But if a value in A is changed from abc to xyz (same applies to B of course) the whole approach breaks.
If you still want to write this into a column you can use the ROW_NUMBER() from above to fill these values initially and a TRIGGER to set the next value with your SELECT MAX()+1 approach for new rows.
If the set of combinations is limited you might create a SEQUENCE (needs v2012+) for each.
But - to be honest - the whole issue smells a bit.

Auto Generate Unique ID separate from Primary Key

I have a Relational database (that I'm new to creating) that has many tables relating to baseball statistical tracking and analysis. The table I'm working on currently is the tbl_PitchLog table, that tracks pitches in an at-bat.
What I'd like to do is eliminate the need for an at-bat table and just use At-Bat Unique ID for a group of pitches. I have a Pitch_ID field, but I'd like SS to generate a new AtBat_ID that I can then reference to get all the pitches of a particular at-bat.
For Example
Pitch_ID | Pitch_Number | Result
1 1 Foul
2 2 Foul
3 3 Strike
4 1 Ball
5 2 Flyout
6 1 Groundout
To be:
Pitch_ID | AtBat_ID | Pitch_Number | Result
1 1 1 Foul
2 1 2 Foul
3 1 3 Strike
4 2 1 Ball
5 2 2 Flyout
6 3 1 Groundout
You don't specify what version of SS you're using, but SQL Server 2012 introduced sequences; you can create an at bat sequence, get the next value when the at bat changes, and use that value for your inserts.
CREATE SEQUENCE at_bat_seq
AS INTEGER
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE <what you want the max to be>
NO CYCLE;
DECLARE #at_bat int;
SET #at_bat = NEXT VALUE FOR at_bat_seq;
Most of the qualifiers are self-explanatory; the [NO] CYCLE specifies whether the value will start over at the min when it hits the max. As defined above, you'll get an error when you get to the max. If you just want it to start over when it gets to the max, then specify CYCLE instead of NO CYCLE.
Create the tbl_PitchLog table with a Pitch_ID as its primary key, while it's at the same time a foreign key taken from the main table.
What you're looking for is a one to one relationship.

Inserting one table's complete column data to a particular column in another table in SQL Server

Inserting one table's complete column data to a particular column in another table in SQL SERVER
I have two tables i.e AuditCalendar, ScheduleAudit
Audit Calendar has two columns Taskid, TaskTypeId
Schedule Audit has two columns Scheduleid, Taskid
Audit Calendar looks like this
Taskid (Auto increment) TaskTypeId
-------------------------------------
1 1
2 2
3 3
4 1
5 1
But I want Taskid column data from Audit Calendar table based on TaskTypeId .Columns
After completion of query, the ScheduleAudit table should look like this
Scheuleid (AutoIncrement) Taskid
-------------------------------------
1 1
2 1
3 1
I have to run this query seems to look like a error
Subquery returns more than one value
Query is:
INSERT INTO ScheduleAudit(TaskId)
VALUES ((SELECT TaskId FROM AuditCalendar Where TaskTypeId = 1))
Please can you suggest how I can do this approach I am new to SQL Server but someone says that use cursors.... I am really confused last 1 week on words. And also search google but not get it now...Please can you give me any one valuable suggestions.
insert ... values is supposed to insert a single row. So what you have in the parentheses is supposed to produce a single row, or else it would fail.
There's no need to use insert ... values, when you can use insert ... select:
INSERT INTO ScheduleAudit(TaskId)
SELECT TaskId FROM AuditCalendar Where TaskTypeId=1
...however, that would produce
1 1
2 4
3 5
I'm not sure I understand the logic behind producing your example output.

How to (or Can I) select a random value from the Postgresql database excluding some particular records?

Is it possible to randomly select a record from the database excluding some records with particular status?
For eg,
For example, I have a table for storing employee details.
id employeename employeestatus
1 ab 1
2 cd 1
3 ef 2
4 gh 1
5 ij 1
What I want from the query is to fetch a single random record whose status is not 2. Is it possible to do so? The database I'm using is PostgreSQL 8.4.15.
TRY This
SELECT *
FROM employee
WHERE employeestatus != 2
ORDER BY RANDOM()
LIMIT 1
Try this other question on the same topic
Best way to select random rows PostgreSQL
It's tricker than you think (to do efficiently)

Resources