I'm writting a migration on Laravel 5.1 and after created a table I rename the table name and the columns, It works running the migration for a MySQL database but on SQL Server 2008 fails trying to rename the columns and outputs the next error:
Next Doctrine\DBAL\DBALException: An exception occurred while executing 'SELECT col.name,
type.name AS type,
col.max_length AS length,
~col.is_nullable AS notnull,
def.definition AS [default],
col.scale,
col.precision,
col.is_identity AS autoincrement,
col.collation_name AS collation,
CAST(prop.value AS NVARCHAR(MAX)) AS comment -- CAST avoids driver error for sql_variant type
FROM sys.columns AS col
JOIN sys.types AS type
ON col.user_type_id = type.user_type_id
JOIN sys.objects AS obj
ON col.object_id = obj.object_id
JOIN sys.schemas AS scm
ON obj.schema_id = scm.schema_id
LEFT JOIN sys.default_constraints def
ON col.default_object_id = def.object_id
AND col.object_id = def.parent_object_id
LEFT JOIN sys.extended_properties AS prop
ON obj.object_id = prop.major_id
AND col.column_id = prop.minor_id
AND prop.name = 'MS_Description'
WHERE obj.type = 'U'
AND (obj.name = 'roles' AND scm.name = SCHEMA_NAME())':
I need that the migration working on both databases. My migration code is:
public function up()
{
Schema::create('cat_tipo_usuario', function (Blueprint $table) {
$table->increments('id_tipo_usuario');
$table->string('txt_tipo_usuario');
$table->timestamps();
});
//Se renombra la tabla
Schema::rename('cat_tipo_usuario','roles');
//Se cambia el nombre de las columnas
Schema::table('roles',function($tabla){
$tabla->renameColumn('id_tipo_usuario','id');
$tabla->renameColumn('txt_tipo_usuario','nombre');
});
}
If I comment the lines where I rename the columns the migration runs correctly, so the driver and the connection are working well.
I think whats causing an issue is you renaming your primary key field.
Please test this migration to see if it solves your :
Schema::table('roles',function($tabla){
$table->dropPrimary('id_tipo_usuario');
$tabla->renameColumn('id_tipo_usuario','id');
$table->primary('id');
$tabla->renameColumn('txt_tipo_usuario','nombre');
});
I think if before renaming, you drop the primary key constraint, it should work out!
Related
I have a couple of stored procedures that create different temporary tables.
At the end of the procedure i drop them (know that is not required, but it's good practice).
The stored procedures are executed as a part of a SSIS package. I got 4 different SQL jobs that execute the same SSIS package running in parallel.
When logging into the Azure portal and using the performance recommendation feature, I get a recommendation to fix the schema issues. It states an Sql error code 208. According to documentation that means "object not found".
Temporary tables are valid within the scope of the stored procedure and should get a unique name in the database, so I do not think where are any conflicts.
I have no idea what causes this, and the stored procedures seems to work alright. Anyone know what could be the cause here?
Simplified sample of one of the procedures:
SET NOCOUNT ON;
CREATE TABLE #tmpTransEan
(
Ean_Art_Str_id BIGINT ,
Artikler_id BIGINT
);
INSERT INTO #tmpTransEan
( Ean_Art_Str_id ,
Artikler_id
)
SELECT DISTINCT
eas.Ean_Art_Str_id ,
a.Artikler_id
FROM dbo.Artikkel_Priser ap
JOIN Ean_Art_Str eas ON eas.artikler_id = ap.Artikler_id
JOIN wsKasse_Til_Kasselogg ktk ON eas.Ean_Art_Str_id = ktk.ID_Primary
JOIN dbo.Artikler a ON a.Artikler_id = eas.artikler_id
JOIN dbo.Felles_Butikker b ON b.Butikker_id = ap.butikker_id
WHERE ktk.ID_Table = OBJECT_ID('Ean_Art_Str')
AND LEN(a.Artikkelnr) >= 8
AND ktk.Tidspunkt >= #tidspunkt
AND ( ( ap.butikker_id = #nButikker_id1
AND #Alle_artikler_til_kasse = 'N'
)
OR ( b.Databaser_id = #Databaser_id
AND #Alle_artikler_til_kasse = 'J'
)
)
AND b.Akt_kode = 'A'
AND a.Akt_kode = 'A'
AND a.Databaser_id IN ( -1, #Databaser_id )
SELECT DISTINCT
a.Artikkelnr ,
s.Storrelse ,
eas.* ,
EAN_12 = LEFT(eas.EAN_13, 12)
FROM dbo.Ean_Art_Str eas
JOIN #tmpTransEan t ON t.Artikler_id = eas.artikler_id
JOIN Artikler a ON a.Artikler_id = eas.artikler_id
JOIN dbo.Felles_Storrelser s ON s.Storrelser_id = eas.storrelser_id
DROP TABLE #tmpTransEan;
END;
This is my sql Query:
SELECT ParkingPlaceName, NoOfParkingPlaces, COUNT(Place.ParkingAreaID) AS NoOfCarsParked, NoOfParkingPlaces-COUNT(Place.ParkingAreaID)
FROM ParkingArea
LEFT JOIN Place ON ParkingArea.ParkingAreaID = Place.ParkingAreaID
LEFT JOIN Car ON Car.CarID = Place.CarID
GROUP BY ParkingPlaceName, NoOfParkingPlaces, Place.ParkingAreaID
how to write in LINQ to SQL Query
I think you can use DefaultIfEmpty method to perform left outer join between 3 tables with let statements to deal with group results, hence the LINQ version from your SQL query should be similar (or same) like below:
var query = from pa in ParkingArea
from pl in Place.Where(x => pa.ParkingAreaID == x.ParkingAreaID).DefaultIfEmpty()
from ca in Car.Where(x => x.CarID == pl.CarID).DefaultIfEmpty()
group new { pa, pl.ParkingAreaID, ca.CarID } by new { pa.ParkingPlaceName, pa.NoOfParkingPlaces, pl.ParkingAreaID } into grp
let ParkingPlaceName = grp.Select(x => x.ParkingPlaceName)
let NoOfParkingPlaces = grp.Select(x => x.NoOfParkingPlaces)
let NoOfCarsParked = grp.Select(x => x.ParkingAreaID).Count()
select new
{
ParkingPlaceName,
NoOfParkingPlaces,
NoOfCarsParked,
AvailableParkingPlaces = NoOfParkingPlaces - NoOfCarsParked // new alias for holding substraction
};
I decided not to use join ... in ... on ... equals ... directly after first and third from clauses, since it may lead into confusion about which table instance should be handled when creating group elements after performing join.
Is it possible to return both objects of a join as the result of a GridGain cache query?
We can get either one of the sides of the join or fields from both (and then use these to retrieve each object separately), but looking at the examples and documentation there seems to be no way to get both objects.
Thanks!
#dejan- In GridGain and Apache Ignite, you can use _key and _val functionality with SqlFieldsQuery in order to return an object. For example -
SqlFieldsQuery sql = new SqlFieldsQuery(
"select a._key, a._val, b._val from SomeTypeA a, SomeTypeB b " +
"where a.id = b.otherId");
try (QueryCursor<List<?>> cursor = cache.query(sql) {
for (List<?> row : cursor)
System.out.println("Row: " + row);
}
Note that in this case the object will be returned in a Serialized form.
First of all, GridGain Open Source edition is now Apache Ignite, so I would recommend switching.
In Ignite, you can return exactly the fields you need from a query using SqlFieldsQuery, like so:
SqlFieldsQuery sql = new SqlFieldsQuery(
"select fieldA1, fieldA2, fieldB3 from SomeTypeA a, SomeTypeB b " +
"where a.id = b.otherId");
try (QueryCursor<List<?>> cursor = cache.query(sql) {
for (List<?> row : cursor)
System.out.println("Row: " + row);
}
In GridGain open source edtion, you can use GridGain fields query APIs as well.
I'm trying to using the Subsonic Fluent query interface to create a simple inner join between two tables:
[SearchJobResults]
PK SearchJobResultId int
Name string
Desc string
[ParseResults]
PK ParseResultId int
Name string
SearchJobResultId int
There is a 1 to 1 relationship between these tables.
Keep in mind, I'm not using ActiveRecord. I have classes for ParseResult and SearchJobResult that work fine.
IDataProvider p = ProviderFactory.GetProvider("DemacDB");
SqlQuery query = new SqlQuery(p);
var q = new Select(p).From("ParseResults")
.InnerJoin<SearchJobResult>("SearchJobResultId","SearchJobResultId").GetRecordCount();
This code throws an exception:
Test method Models.SearchTests.TestSubsonicQueryMethods threw exception: System.InvalidOperationException: Don't know which column to join to - can't find column SearchJobResultId in table ParseResults.
I've looked at the source code for SubSonic to see where this execption is coming from:
private void CreateJoin<T>(string fromColumnName, string toColumnName, Join.JoinType type)
{
//see if we can find the table
var toTable = _provider.FindOrCreateTable(typeof(T));
//the assumption here is that the FromTable[0] is the table to join from
if(FromTables.Count == 0)
throw new InvalidOperationException("Can't join if there's no table to join to - make sure to use From() before InnerJoin");
if(toTable == null)
throw new InvalidOperationException("Can't find the table for this type. Try using the Column instead");
var fromColumn = FromTables[0].GetColumn(fromColumnName);
if(fromColumn == null)
throw new InvalidOperationException("Don't know which column to join to - can't find column " + fromColumnName + " in table " + FromTables[0].Name);
var toColumn = toTable.GetColumn(toColumnName);
if(toColumn == null)
throw new InvalidOperationException("Don't know which column to join to - can't find column " + toColumnName + " in table " + toTable.Name);
CreateJoin(fromColumn, toColumn, Join.JoinType.Inner);
}
I've tried using Aliases but that fails. Additionally, if I just do a simple query like this it works fine:
var d = new Select(p).From("ParseResults").GetRecordCount();
Turns out you need to use the Typed T overloads of From/Join to get this working.
var b = new Select(p).From<ParseResult>().InnerJoin<SearchJobResult>("SearchJobResultId", "SearchJobResultId").GetRecordCount();
Works as the FromTables collection in Subsonic now correctly gets enumerated because it's reading the type from the actual object and not the DB.
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.