How to Allow Only One Row for a Table

How to allow only one row for a table?

A UNIQUE constraint allows multiple rows with NULL values, because two NULL values are never considered to be the same.

Similar considerations apply to CHECK constraints. They allow the expression to be TRUE or NULL (just not FALSE). Again, NULL values get past the check.

To rule that out, the column must be defined NOT NULL. Or make it the PRIMARY KEY since PK columns are defined NOT NULL automatically. Details:

  • Why can I create a table with PRIMARY KEY on a nullable column?

Also, just use boolean:

CREATE TABLE public.onerow (
onerow_id bool PRIMARY KEY DEFAULT TRUE
, data text
, CONSTRAINT onerow_uni CHECK (onerow_id)
);

The CHECK constraint can be that simple for a boolean column. Only TRUE is allowed.

You may want to REVOKE (or not GRANT) the DELETE and TRUNCATE privileges from public (and all other roles) to prevent the single row from ever being deleted. Like:

REVOKE DELETE, TRUNCATE ON public.onerow FROM public;

Only allow one row with main flag up in a table

You can create a unique index on the pair of columns:

UNIQUE KEY uix_1 (jobid, main)

The unique index permits multiple NULL values nullable columns so the pair (1, NULL) could be inserted multiple times but the pair (1, 1) could be inserted only once.

If you want to constrain the values for main column to 1 and NULL you have some options:

  • Use CHECK constraint – requires MySQL 8
  • Use ENUM('yes') – using numbers as enum values have gotchas
  • Create FOREIGN KEY (main) REFERENCES main_values(main)
  • Use BIT(1) datatype – this will permits 0 as well

How can I ensure that there is one-and-only-one row in DB table?

Two suggestions for you, one or both which may work depending on the particulars of the data you're trying to store:

  • See if the ENUM or SET constraints will work for you; note that they offer differing levels of enforcement based on SQL mode (e.g., strict). See more info:

    http://dev.mysql.com/doc/refman/5.0/en/constraint-invalid-data.html

AND/OR

  • Implement INSERT, UPDATE, and DELETE triggers to control access on the data (you may want to populate the data initially before you create these; again, it depends on your scenario)

    http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html

Constrain a table to have only one row

I just solved the same problem on SQL Server 2008 by creating a table with a computed column and putting the primary key on that column:

CREATE TABLE MyOneRowTable (
[id] AS (1) PERSISTED NOT NULL CONSTRAINT pk_MyOneRowTable PRIMARY KEY,
-- rest of the columns go here
);

Make only one row selectable at a time in React Table 7.1.0

I know this is an old question, but maybe someone will find this solution useful. Since version 7, react-table provides a stateReducer that can be used to track and change the state of a table. (before v7 it had reducerHandlers, but I didn't go deep into that). You can modify the state as follows:

useTable(
{
columns,
data,
stateReducer: (newState, action) => {
if (action.type === "toggleRowSelected") {
newState.selectedRowIds = {
[action.id]: true
}
}

return newState;
},
}
...

Here is the CodeSandbox with the changes described

SQL Server: how to constrain a table to contain a single row?

You make sure one of the columns can only contain one value, and then make that the primary key (or apply a uniqueness constraint).

CREATE TABLE T1(
Lock char(1) not null,
/* Other columns */,
constraint PK_T1 PRIMARY KEY (Lock),
constraint CK_T1_Locked CHECK (Lock='X')
)

I have a number of these tables in various databases, mostly for storing config. It's a lot nicer knowing that, if the config item should be an int, you'll only ever read an int from the DB.

Expand only one row in the table

You are using same fullViewFlag multiple times, so it will effect all the rows. So, I suggest you maintain different fullViewFlag properties for each object and can try the below code

Working stackblitz

TS file

export class AppComponent {
name = 'Angular ' + VERSION.major;

lfilist = [{
desc: [1, 2, 3, 4, 5, 6]
}, {
desc: [7, 8, 9, 10, 11, 12]
}, {
desc: [13, 14, 15, 16, 17, 18]
}].map(item => {
return {
...item,
fullViewFlag: false
}
});
}

Template file

<tr *ngFor="let lfiexport of lfilist">
<td (click)="lfiexport.fullViewFlag = !lfiexport.fullViewFlag" class="text-left">
<span>{{lfiexport.fullViewFlag ? lfiexport.desc : lfiexport.desc | slice:0:2}}</span>
</td>
</tr>

No need of *ngIf we can use terinary operator ?:

Choosing files from only one row in a table angular

Here are some modification that will maintain the list of files with the actual record (row).

First modify the listes data model:

{
name: "A",
qty: 6,
value: 10,
files: [] // added files array here
},

Next, modify the getFileDetails code. You need the index and the target. Then, find the list by index and push the target.files onto that listes object (row):

  getFileDetails (index, e) {
//console.log (e.target.files);
for (var i = 0; i < e.target.files.length; i++) {
this.listes[index].files.push(e.target.files[i]);
}
console.log(this.myFiles)
}

Change the delete method to delete the selected file from the selected index. In this case we need two indexes, one for the list and one for the files. These are created inside the HTML (below):

  deleteRow(listIndex: number, fileIndex: number) {
this.listes[listIndex].files.splice(fileIndex,1);
}

Finally the changes necessary to the html are minimal, but relate to the indexes I mentioned above:

                <tbody>
<tr *ngFor="let list of listes; index as listIndex">
<td>{{listIndex+1}}</td>
<td>{{list.name}}</td>
<td>{{list.qty}}</td>
<td>{{list.value}}</td>
<div style="overflow: auto;">
<td>
<div>
<ng-container>
<input type="file" multiple
(change)="getFileDetails(listIndex, $event)">
</ng-container>
</div>
<div *ngFor="let file of list.files; index as fileIndex">
<div>* {{file.name}}</div>
<button type="button" (click)="deleteRow(listIndex, fileIndex)" class="btn btn-primary">X</button>
</div>
</td>
</div>
</tr>
</tbody>

OP asked about clearing the file input after files are deleted. The following change accomplishes that:

    <input #fileInput type="file" multiple (change)="getFileDetails(listIndex, $event)">
</ng-container>
</div>
<div *ngFor="let file of list.files; index as fileIndex">
<div>* {{file.name}}</div>
<button type="button" (click)="deleteRow(listIndex, fileIndex); fileInput.value = ''" class="btn btn-primary">X</button>

The working blitz can be found here: https://stackblitz.com/edit/angular-ivy-gepzrz?file=src%2Fapp%2Fapp.component.html



Related Topics



Leave a reply



Submit