I'm trying to add a new column to ProjectRecord table and i want to allow null values,
Code:
SchemaBuilder.AlterTable("ProjectRecord", table => table.AddColumn("Related", DbType.Int32));
Thanks.
Krbnr.
.AddColumn<int>("Related", c => c.Nullable())
Related
I'd like to update the value of column A by applying a function to column B.
Is there a simple solution of the form:
knex('table')
.update({
colA: func(${colB})
})
Yes, there is a way to do this within Knex.
For SQL functions which don’t have explicit support in Knex you use knex.raw(SQLstring, parmArray) to encapsulate a SQL snippet or knex.schema.raw(...) to produce an entire SQL statement. And you use single question marks ? for value replacements, and double question marks ?? for field identifier replacements. (see link)
So the SQL: UPDATE table SET colA = func(colB)
... can be produced by including a SQL snippet: (you were close)
knex('table')
.update({
colA: knex.raw( 'func(??)', ['colB'] )
})
... or as full raw SQL:
knex.schema.raw( 'UPDATE table SET ?? = func(??)', ['colA', 'colB'] )
Cheers, Gary.
I have an Object that maps column names to values. The columns to be updated are not known beforehand and are decided at run-time.
e.g. map = {col1: "value1", col2: "value2"}.
I want to execute an UPDATE query, updating a table with those columns to the corresponding values. Can I do the following? If not, is there an elegant way of doing it without building the query manually?
db.none('UPDATE mytable SET $1 WHERE id = 99', map)
is there an elegant way of doing it without building the query manually?
Yes, there is, by using the helpers for SQL generation.
You can pre-declare a static object like this:
const cs = new pgp.helpers.ColumnSet(['col1', 'col2'], {table: 'mytable'});
And then use it like this, via helpers.update:
const sql = pgp.helpers.update(data, cs) + /* WHERE clause with the condition */;
// and then execute it:
db.none(sql).then(data => {}).catch(error => {})
This approach will work with both a single object and an array of objects, and you will just append the update condition accordingly.
See also: PostgreSQL multi-row updates in Node.js
What if the column names are not known beforehand?
For that see: Dynamic named parameters in pg-promise, and note that a proper answer would depend on how you intend to cast types of such columns.
Something like this :
map = {col1: "value1", col2: "value2",id:"existingId"}.
db.none("UPDATE mytable SET col1=${col1}, col2=${col2} where id=${id}", map)
So I have the following code used as a validation method:
if (TableQuery[UsersTable].filter(_.name === login).exists.run) {
val id = TableQuery[UsersTable].filter(_.name === login).firstOption.get.id
val name = TableQuery[UsersTable].filter(_.id === id).firstOption.get.name
}
if you're wondering, I check to make sure of .exists before I query the next two times because the login value can be equal to two columns in the database.
Anyways, I get [SlickException: Read NULL value (null) for ResultSet column Path s2._5] when attempting to get the id above, and I'm unsure why. There should be a first option there because the code has already validated a row exists for the requirements typed beforehand. No "id" column values are null.
How can I get this id value working correctly?
One of the involved columns is nullable but you didn't specify it as Option[...] in the Table.
Using orchad 1.6 in the migration file I have just altered a table and added a column. I need this column to be NotNull, but it doesnt allow you to alter a table enter a NotNull type, so i've used Nullable and entered data into the existing columns.
I then want to edit this column and change it to a Nullable, but am unsure how....
public int UpdateFrom37()
{
SchemaBuilder.AlterTable("ManufacturedProductOrders", table => table
.AddColumn<DateTime>("DateOrdered", c => c.Nullable())
);
return 38;
}
public int UpdateFrom38()
{
SchemaBuilder.AlterTable("ManufacturedProductOrders", table => table
.AlterColumn("DateOrdered", c => c.WithType(dbType.???????????
);
}
I guess you want to change from NULL to NOT NULL, right? The code above clearly states that you already have a nullable column.
AlterColumn command does not currently allow changing column 'nullability'.
Your best option is to issue a manual ALTER TABLE command through SchemaBuilder.ExecuteSql() or directly in the database. You can read about it eg. here.
I want to perform a simple join on two tables (BusinessUnit and UserBusinessUnit), so I can get a list of all BusinessUnits allocated to a given user.
The first attempt works, but there's no override of Select which allows me to restrict the columns returned (I get all columns from both tables):
var db = new KensDB();
SqlQuery query = db.Select
.From<BusinessUnit>()
.InnerJoin<UserBusinessUnit>( BusinessUnitTable.IdColumn, UserBusinessUnitTable.BusinessUnitIdColumn )
.Where( BusinessUnitTable.RecordStatusColumn ).IsEqualTo( 1 )
.And( UserBusinessUnitTable.UserIdColumn ).IsEqualTo( userId );
The second attept allows the column name restriction, but the generated sql contains pluralised table names (?)
SqlQuery query = new Select( new string[] { BusinessUnitTable.IdColumn, BusinessUnitTable.NameColumn } )
.From<BusinessUnit>()
.InnerJoin<UserBusinessUnit>( BusinessUnitTable.IdColumn, UserBusinessUnitTable.BusinessUnitIdColumn )
.Where( BusinessUnitTable.RecordStatusColumn ).IsEqualTo( 1 )
.And( UserBusinessUnitTable.UserIdColumn ).IsEqualTo( userId );
Produces...
SELECT [BusinessUnits].[Id], [BusinessUnits].[Name]
FROM [BusinessUnits]
INNER JOIN [UserBusinessUnits]
ON [BusinessUnits].[Id] = [UserBusinessUnits].[BusinessUnitId]
WHERE [BusinessUnits].[RecordStatus] = #0
AND [UserBusinessUnits].[UserId] = #1
So, two questions:
- How do I restrict the columns returned in method 1?
- Why does method 2 pluralise the column names in the generated SQL (and can I get round this?)
I'm using 3.0.0.3...
So far my experience with 3.0.0.3 suggests that this is not possible yet with the query tool, although it is with version 2.
I think the preferred method (so far) with version 3 is to use a linq query with something like:
var busUnits = from b in BusinessUnit.All()
join u in UserBusinessUnit.All() on b.Id equals u.BusinessUnitId
select b;
I ran into the pluralized table names myself, but it was because I'd only re-run one template after making schema changes.
Once I re-ran all the templates, the plural table names went away.
Try re-running all 4 templates and see if that solves it for you.