Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Leitfaden wird erläutert, wie Sie eine Azure SQL-Datenbank einrichten und mit einer Power Apps-Code-App mithilfe des Power SDK verbinden.
Hinweis
Previewfunktionen sind nicht für den Produktionseinsatz gedacht und können eine eingeschränkte Funktionalität aufweisen. Diese Funktionen sind vor einer offiziellen Veröffentlichung verfügbar, damit Kunden frühzeitig zugreifen und Feedback geben können.
In diesem Leitfaden werden folgende Themen behandelt:
- Bereitstellen eines Azure SQL Server und einer Datenbank
- Erstellen von SQL-Tabellen und gespeicherten Prozeduren
- Verbinden einer Power Apps-Code-App mit dem Power SDK
Voraussetzungen
- Ein Azure-Abonnement
- Zugriff auf das Azure-Portal
- Power Platform-Umgebung mit aktivierten Code-Apps
- Visual Studio Code
- Node.js (LTS-Version)
- Power Platform Tools für VS Code
- SQL Server (mssql) VS Code-Erweiterung
Einrichten von Azure SQL Server und Datenbank
- Navigieren Sie zur Option "SQL-Bereitstellung auswählen" – Microsoft Azure
- Sql-Datenbank auswählen -> Ressourcentyp: Einzelne Datenbank ->Create
- Ausfüllen:
- Ressourcengruppe: Wählen Sie " Neu erstellen" aus, und geben Sie einen Ressourcengruppennamen ein, z. B.
rg-codeapps-dev - Datenbankname:
sqldb-codeapps-dev - Server: Wählen Sie "Neu erstellen" und füllen Sie aus:
- Server-Name:
sql-codeapps-dev - Standort: Wählen Sie die nächstgelegene Region ihrer Power Platform-Umgebung aus.
- Authentifizierungsmethode: Microsoft Entra-only-Authentifizierung verwenden
- Microsoft Entra-Administrator festlegen: Wählen Sie "Administrator festlegen" und dann Ihren eigenen Benutzer aus.
- Server-Name:
- Wählen Sie OK aus
- Ressourcengruppe: Wählen Sie " Neu erstellen" aus, und geben Sie einen Ressourcengruppennamen ein, z. B.
- Compute + Speicher: Allgemeiner Zweck – Serverless
- Klicken Sie auf Weiter: Netzwerk.
- Ausfüllen:
- Konnektivitätsmethode: Öffentlicher Endpunkt
- Zulassen, dass Azure-Dienste und -Ressourcen auf diesen Server zugreifen können: Ja
- Aktuelle Client-IP-Adresse hinzufügen: Ja
- Wählen Sie "Überprüfen" und ">" aus.
- Warten Sie, bis die Bereitstellung abgeschlossen ist, und wählen Sie dann "Zur Ressource wechseln" aus.
Bereitstellen von Beispieldaten
Wählen Sie in Visual Studio Code Erweiterungen (STRG+UMSCHALT+X) aus.
Suchen Sie die SQL Server-Erweiterung (mssql) auf der Aktivitätsleiste, und öffnen Sie sie, oder verwenden Sie STRG+ALT+D.
Wählen Sie unter "Verbindungen" +Verbindung hinzufügen
Wählen Sie im Dialogfeld "Mit Datenbank verbinden" die Option "Azure durchsuchen" aus, wählen Sie Ihr Abonnement, die Ressourcengruppe (z. B.:
rg-codeapps-dev), den Server (z. B.:sql-codeapps-dev) und dann die Datenbank (z. B.:sqldb-codeapps-dev) aus.Wählen Sie unter "Authentifizierungstyp" die Option "Microsoft Entra ID – Universal" mit MFA-Unterstützung aus.
Stellen Sie sicher, dass Ihr Azure-Portal in Ihrem Browser geöffnet ist, und wählen Sie dann "Anmelden" aus. Sie sollten aufgefordert werden, sich anzumelden, und dann sehen Sie:
Wählen Sie "Verbinden" aus.
Klicken Sie im SQL SERVER-Bereich mit der rechten Maustaste auf Ihre Datenbank, und wählen Sie "Neue Abfrage" aus.
Fügen Sie im neuen Abfragefenster die folgende SQL-Datei ein:
-- Drop existing objects if they exist IF OBJECT_ID('dbo.Projects', 'U') IS NOT NULL DROP TABLE dbo.Projects; -- ============================================= -- CREATE TABLES -- ============================================= -- Projects Table CREATE TABLE [dbo].[Projects]( [ProjectId] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](255) NOT NULL, [Description] [nvarchar](max) NULL, [StartDate] [date] NULL, [EndDate] [date] NULL, [Status] [nvarchar](50) NOT NULL DEFAULT ('Planning'), [Priority] [nvarchar](20) NOT NULL DEFAULT ('Medium'), [Budget] [decimal](18, 2) NULL, [ProjectManagerEmail] [nvarchar](255) NOT NULL, [CreatedBy] [nvarchar](255) NOT NULL, [CreatedDate] [datetime2](7) NOT NULL DEFAULT (getutcdate()), [IsActive] [bit] NOT NULL DEFAULT (1), CONSTRAINT [PK_Projects] PRIMARY KEY ([ProjectId]) ); GO -- ============================================= -- ADD CONSTRAINTS -- ============================================= -- Project Status Check ALTER TABLE [dbo].[Projects] ADD CONSTRAINT [CK_Projects_Status] CHECK ([Status] IN ('Planning', 'Active', 'On Hold', 'Completed', 'Cancelled')); -- Project Priority Check ALTER TABLE [dbo].[Projects] ADD CONSTRAINT [CK_Projects_Priority] CHECK ([Priority] IN ('Low', 'Medium', 'High', 'Critical')); GO -- ============================================= -- STORED PROCEDURES -- ============================================= -- Get All Projects IF OBJECT_ID('dbo.GetAllProjects', 'P') IS NOT NULL DROP PROCEDURE dbo.GetAllProjects; GO CREATE PROCEDURE [dbo].[GetAllProjects] AS BEGIN SET NOCOUNT ON; SELECT [ProjectId], [Name], [Description], [StartDate], [EndDate], [Status], [Priority], [Budget], [ProjectManagerEmail], [CreatedBy], [CreatedDate], [IsActive] FROM [dbo].[Projects] WHERE [IsActive] = 1 ORDER BY [CreatedDate] DESC; END GO -- Create Project IF OBJECT_ID('dbo.CreateProject', 'P') IS NOT NULL DROP PROCEDURE dbo.CreateProject; GO CREATE PROCEDURE [dbo].[CreateProject] @Name NVARCHAR(255), @Description NVARCHAR(MAX) = NULL, @StartDate DATE = NULL, @EndDate DATE = NULL, @Status NVARCHAR(50) = 'Planning', @Priority NVARCHAR(20) = 'Medium', @Budget DECIMAL(18,2) = NULL, @ProjectManagerEmail NVARCHAR(255), @CreatedBy NVARCHAR(255) AS BEGIN SET NOCOUNT ON; INSERT INTO [dbo].[Projects] ( [Name], [Description], [StartDate], [EndDate], [Status], [Priority], [Budget], [ProjectManagerEmail], [CreatedBy] ) VALUES ( @Name, @Description, @StartDate, @EndDate, @Status, @Priority, @Budget, @ProjectManagerEmail, @CreatedBy ); SELECT SCOPE_IDENTITY() as ProjectId; END GO -- Update Project IF OBJECT_ID('dbo.UpdateProject', 'P') IS NOT NULL DROP PROCEDURE dbo.UpdateProject; GO CREATE PROCEDURE [dbo].[UpdateProject] @ProjectId INT, @Name NVARCHAR(255) = NULL, @Description NVARCHAR(MAX) = NULL, @StartDate DATE = NULL, @EndDate DATE = NULL, @Status NVARCHAR(50) = NULL, @Priority NVARCHAR(20) = NULL, @Budget DECIMAL(18,2) = NULL, @ProjectManagerEmail NVARCHAR(255) = NULL AS BEGIN SET NOCOUNT ON; UPDATE [dbo].[Projects] SET [Name] = ISNULL(@Name, [Name]), [Description] = ISNULL(@Description, [Description]), [StartDate] = ISNULL(@StartDate, [StartDate]), [EndDate] = ISNULL(@EndDate, [EndDate]), [Status] = ISNULL(@Status, [Status]), [Priority] = ISNULL(@Priority, [Priority]), [Budget] = ISNULL(@Budget, [Budget]), [ProjectManagerEmail] = ISNULL(@ProjectManagerEmail, [ProjectManagerEmail]) WHERE [ProjectId] = @ProjectId AND [IsActive] = 1; SELECT @@ROWCOUNT as RowsAffected; END GO -- Delete Project (Soft Delete) IF OBJECT_ID('dbo.DeleteProject', 'P') IS NOT NULL DROP PROCEDURE dbo.DeleteProject; GO CREATE PROCEDURE [dbo].[DeleteProject] @ProjectId INT AS BEGIN SET NOCOUNT ON; UPDATE [dbo].[Projects] SET [IsActive] = 0 WHERE [ProjectId] = @ProjectId AND [IsActive] = 1; SELECT @@ROWCOUNT as RowsAffected; END GO -- ============================================= -- SAMPLE DATA -- ============================================= -- Insert Sample Projects INSERT INTO [dbo].[Projects] ([Name], [Description], [StartDate], [EndDate], [Status], [Priority], [Budget], [ProjectManagerEmail], [CreatedBy]) VALUES ('Website Redesign', 'Complete redesign of company website with modern UI/UX', '2025-06-01', '2025-08-31', 'Active', 'High', 75000.00, 'sarah.johnson@company.com', 'admin@company.com'), ('Mobile App Development', 'Develop iOS and Android mobile application for customer portal', '2025-07-01', '2025-12-31', 'Planning', 'Critical', 150000.00, 'mike.chen@company.com', 'admin@company.com'), ('Database Migration', 'Migrate legacy database to cloud infrastructure', '2025-05-15', '2025-09-30', 'Active', 'Medium', 50000.00, 'lisa.williams@company.com', 'admin@company.com'); GO PRINT 'Projects-only database schema created successfully with sample data!';Wählen Sie das grüne Wiedergabesymbol (STRG-UMSCHALT-E) aus, um die Abfrage auszuführen.
In der ABFRAGEERGEBNISSE-Ausgabe sollten keine Fehler angezeigt werden.
Initialisiere deine Code-App
Falls noch nicht, erstellen und/oder initialisieren Sie Ihre Code-App mithilfe der hier aufgeführten Anweisungen: Erstellen Sie eine App von Grund auf neu.
Erstellen einer SQL Server-Verbindung in Power Platform
Öffnen von Power Apps
Wählen Sie Ihre Umgebung aus
Navigieren Sie zu "Verbindungen". Es könnte im ... Mehr-Menü sein.
Wählen Sie + Neue Verbindung aus.
SQL Server auswählen
Authentifizierungstyp auswählen: Microsoft Entra ID Integrated
Wählen Sie "Erstellen " aus, und melden Sie sich in der Popupauthentifizierungsaufforderung an.
Hinzufügen von SQL-Tabellenverbindungen zu Ihrer App
Auflisten der verfügbaren Verbindungen in Ihrer Umgebung. Die erstellte Verbindung sollte angezeigt werden:
pac connection listEs sollte eine Liste angezeigt werden, die ähnlich wie die folgende ist:
Um die Projekttabelle zum Projekt hinzuzufügen, kopieren Sie die Verbindungs-ID (die erste Spalte), und verwenden Sie den folgenden Befehl:
pac code add-data-source -a "shared_sql" -c "[CONNECTION ID]" -d "[SQL SERVER NAME].database.windows.net,[DATA BASE NAME]" -sp "dbo.GetAllProjects"Beispiel:
pac code add-data-source -a "shared_sql" -c "aaaa0000bb11222233cc444444dddddd" -d "sql-codeapps-dev.database.windows.net,sqldb-codeapps-dev" -sp "dbo.GetAllProjects"Öffnen Sie die Ordner
ServicesundModelsund betrachten Sie den neu generierten Code.
Tabelle mit Projekten hinzufügen
Wir verwenden Fluent UI, um eine Tabelle mit Projekten anzuzeigen. Führen Sie ein Downgrade auf React 18 durch und installieren Sie es mit:
npm install react@^18.0.0 react-dom@^18.0.0 @types/react@^18.0.0 @types/react-dom@^18.0.0 npm install @fluentui/react-componentsFügen Sie eine neue Datei unter
srcdem NamenProjectsTable.tsxmit dem folgenden Code hinzu:/** * ProjectsTable Component - Displays project data from Power Platform in a sortable DataGrid */ import React, { useEffect, useState, useCallback, useMemo } from 'react'; import { DataGrid, DataGridHeader, DataGridRow, DataGridHeaderCell, DataGridCell, DataGridBody, TableColumnDefinition, TableRowId, Spinner, MessageBar, Badge, makeStyles, tokens, } from '@fluentui/react-components'; import { GetAllProjectsService } from './Services/GetAllProjectsService'; // String formatting utility for localizable messages const formatMessage = (template: string, params: Record<string, string | number> = {}): string => { return template.replace(/\{(\w+)\}/g, (match, key) => { const value = params[key]; return value !== undefined ? String(value) : match; }); }; // Common UI messages const MESSAGE_STRINGS = { LOADING: 'Loading data...', NO_DATA: 'No data found.', GENERIC_ERROR: 'An unexpected error occurred', LOAD_ERROR: 'Failed to load data. Please try again.', PROJECT_COUNTER_SINGLE: 'Showing {count} project', PROJECT_COUNTER_PLURAL: 'Showing {count} projects', COLUMN_PROJECT_NAME: 'Project Name', COLUMN_DESCRIPTION: 'Description', COLUMN_START_DATE: 'Start Date', COLUMN_END_DATE: 'End Date', COLUMN_STATUS: 'Status', COLUMN_PRIORITY: 'Priority', ARIA_LABEL_DATA_GRID: 'Projects data grid', } as const; // Project data type type ProjectItem = { ProjectId?: number; Name?: string; Description?: string; StartDate?: string; EndDate?: string; Status?: string; Priority?: string; Budget?: number; ProjectManagerEmail?: string; CreatedBy?: string; CreatedDate?: string; IsActive?: boolean; }; // DataGrid columns const COLUMNS: TableColumnDefinition<ProjectItem>[] = [ { columnId: 'name', compare: (a, b) => (a.Name || '').localeCompare(b.Name || ''), renderHeaderCell: () => MESSAGE_STRINGS.COLUMN_PROJECT_NAME, renderCell: (item) => item.Name || '', }, { columnId: 'description', compare: (a, b) => (a.Description || '').localeCompare(b.Description || ''), renderHeaderCell: () => MESSAGE_STRINGS.COLUMN_DESCRIPTION, renderCell: (item) => item.Description || '', }, { columnId: 'startDate', compare: (a, b) => new Date(a.StartDate || '').getTime() - new Date(b.StartDate || '').getTime(), renderHeaderCell: () => MESSAGE_STRINGS.COLUMN_START_DATE, renderCell: (item) => item.StartDate ? new Date(item.StartDate).toLocaleDateString() : '', }, { columnId: 'endDate', compare: (a, b) => new Date(a.EndDate || '').getTime() - new Date(b.EndDate || '').getTime(), renderHeaderCell: () => MESSAGE_STRINGS.COLUMN_END_DATE, renderCell: (item) => item.EndDate ? new Date(item.EndDate).toLocaleDateString() : '', }, { columnId: 'status', compare: (a, b) => (a.Status || '').localeCompare(b.Status || ''), renderHeaderCell: () => MESSAGE_STRINGS.COLUMN_STATUS, renderCell: (item) => <StatusBadge status={item.Status || ''} />, }, { columnId: 'priority', compare: (a, b) => (a.Priority || '').localeCompare(b.Priority || ''), renderHeaderCell: () => MESSAGE_STRINGS.COLUMN_PRIORITY, renderCell: (item) => <PriorityBadge priority={item.Priority || ''} />, }, ]; // Row ID generator const getRowId = (item: ProjectItem): TableRowId => item.ProjectId?.toString() || `temp-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`; // Extracts a user-friendly error message from various error types const extractErrorMessage = ( error: unknown, fallbackMessage = MESSAGE_STRINGS.GENERIC_ERROR ): string => { if (error instanceof Error) { return error.message; } if (typeof error === 'string') { return error; } return fallbackMessage; }; // Badge component for Priority const PriorityBadge: React.FC<{ priority: string }> = React.memo(({ priority }) => { const styles = useStyles(); const badgeProps = useMemo(() => { const getPriorityAppearance = (priority: string) => { switch (priority?.toLowerCase()) { case 'critical': return { appearance: 'filled' as const, color: 'danger' as const }; case 'high': return { appearance: 'filled' as const, color: 'important' as const }; case 'medium': return { appearance: 'filled' as const, color: 'warning' as const }; case 'low': return { appearance: 'filled' as const, color: 'success' as const }; default: return { appearance: 'outline' as const, color: 'subtle' as const }; } }; return getPriorityAppearance(priority); }, [priority]); return ( <Badge {...badgeProps} className={styles.badge}> {priority || 'Unknown'} </Badge> ); }); PriorityBadge.displayName = 'PriorityBadge'; // Badge component for Status const StatusBadge: React.FC<{ status: string }> = React.memo(({ status }) => { const styles = useStyles(); const badgeProps = useMemo(() => { const getStatusAppearance = (status: string) => { switch (status?.toLowerCase()) { case 'completed': return { appearance: 'filled' as const, color: 'success' as const }; case 'active': return { appearance: 'filled' as const, color: 'brand' as const }; case 'planning': return { appearance: 'filled' as const, color: 'informative' as const }; case 'on hold': return { appearance: 'filled' as const, color: 'warning' as const }; case 'cancelled': return { appearance: 'filled' as const, color: 'danger' as const }; default: return { appearance: 'outline' as const, color: 'subtle' as const }; } }; return getStatusAppearance(status); }, [status]); return ( <Badge {...badgeProps} className={styles.badge}> {status || 'Unknown'} </Badge> ); }); StatusBadge.displayName = 'StatusBadge'; // Styles const useStyles = makeStyles({ container: { padding: tokens.spacingVerticalXXL, }, loadingContainer: { display: 'flex', alignItems: 'center', gap: tokens.spacingHorizontalS, padding: tokens.spacingVerticalXXL, }, messageBar: { marginBottom: tokens.spacingVerticalXL, }, projectCounter: { marginBottom: tokens.spacingVerticalM, fontSize: tokens.fontSizeBase200, color: tokens.colorNeutralForeground2, }, dataGrid: { width: '100%', }, badge: { fontSize: tokens.fontSizeBase200, fontWeight: tokens.fontWeightMedium, textTransform: 'capitalize', }, }); // Custom hook to fetch and manage project data const useProjectsData = (): { projects: ProjectItem[]; loading: boolean; error: string | null; refetch: () => Promise<void>; } => { const [projects, setProjects] = useState<ProjectItem[]>([]); const [loading, setLoading] = useState(true); const [error, setError] = useState<string | null>(null); const fetchProjects = useCallback(async () => { try { setLoading(true); setError(null); const result = await GetAllProjectsService.GetAllProjects(); if (result.success && result.data?.ResultSets?.Table1) { const projectsData = Array.isArray(result.data.ResultSets.Table1) ? result.data.ResultSets.Table1 as ProjectItem[] : [result.data.ResultSets.Table1] as ProjectItem[]; setProjects(projectsData); } else { const errorMsg = result.error instanceof Error ? result.error.message : result.error || MESSAGE_STRINGS.LOAD_ERROR; setError(errorMsg); console.error('Failed to fetch projects:', result.error); } } catch (error) { const errorMessage = extractErrorMessage(error, MESSAGE_STRINGS.GENERIC_ERROR); setError(errorMessage); console.error('Error fetching projects:', error); } finally { setLoading(false); } }, []); useEffect(() => { fetchProjects(); }, [fetchProjects]); return { projects, loading, error, refetch: fetchProjects }; }; // UI Components const LoadingSpinner: React.FC = () => { const styles = useStyles(); return ( <div className={styles.loadingContainer}> <Spinner size="small" /> <span>{MESSAGE_STRINGS.LOADING}</span> </div> ); }; const ErrorMessage: React.FC<{ error: string }> = ({ error }) => { const styles = useStyles(); return ( <MessageBar intent="error" className={styles.messageBar}> {error} </MessageBar> ); }; const EmptyState: React.FC = () => { const styles = useStyles(); return ( <MessageBar intent="info" className={styles.messageBar} style={{ textAlign: 'center' }}> {MESSAGE_STRINGS.NO_DATA} </MessageBar> ); }; const ProjectCounter: React.FC<{ count: number }> = ({ count }) => { const styles = useStyles(); const counterMessage = useMemo(() => { return count === 1 ? formatMessage(MESSAGE_STRINGS.PROJECT_COUNTER_SINGLE, { count }) : formatMessage(MESSAGE_STRINGS.PROJECT_COUNTER_PLURAL, { count }); }, [count]); return ( <div className={styles.projectCounter}> {counterMessage} </div> ); }; // Main component const ProjectsTable: React.FC = () => { const styles = useStyles(); const { projects, loading, error } = useProjectsData(); const projectCount = useMemo(() => projects.length, [projects.length]); const memoizedProjects = useMemo(() => projects, [projects]); const dataGridProps = useMemo(() => ({ items: memoizedProjects, columns: COLUMNS, sortable: true, getRowId, focusMode: "cell" as const, className: styles.dataGrid, "aria-label": MESSAGE_STRINGS.ARIA_LABEL_DATA_GRID, }), [memoizedProjects, styles.dataGrid]); if (loading) { return ( <div className={styles.container}> <LoadingSpinner /> </div> ); } if (error) { return ( <div className={styles.container}> <ErrorMessage error={error} /> </div> ); } if (projectCount === 0) { return ( <div className={styles.container}> <EmptyState /> </div> ); } return ( <div className={styles.container}> <ProjectCounter count={projectCount} /> <DataGrid {...dataGridProps}> <DataGridHeader> <DataGridRow> {({ renderHeaderCell }) => ( <DataGridHeaderCell>{renderHeaderCell()}</DataGridHeaderCell> )} </DataGridRow> </DataGridHeader> <DataGridBody<ProjectItem>> {({ item, rowId }) => ( <DataGridRow<ProjectItem> key={rowId}> {({ renderCell }) => ( <DataGridCell>{renderCell(item)}</DataGridCell> )} </DataGridRow> )} </DataGridBody> </DataGrid> </div> ); }; export default React.memo(ProjectsTable);Fügen Sie
FluentProviderundProjectsTablezumaint.tsxhinzu.import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import PowerProvider from './PowerProvider.tsx' import { FluentProvider, webLightTheme } from '@fluentui/react-components' import ProjectsTable from './ProjectsTable.tsx' createRoot(document.getElementById('root')!).render( <StrictMode> <PowerProvider> <FluentProvider theme={webLightTheme}> <ProjectsTable /> </FluentProvider> </PowerProvider> </StrictMode>, )Führen Sie Ihre App aus mit:
npm run devÖffnen Sie im daraufhin geöffneten Befehlsfenster den bereitgestellten App-Link:
Wenn die App geöffnet wird, sollte ein Zustimmungsdialogfeld angezeigt werden, wählen Sie "Zulassen" aus.
Du solltest ein Datenraster der Projekte sehen:
Veröffentlichen der App in Power Apps
Nachdem Ihre App für die Veröffentlichung und Freigabe bereit ist, stellen Sie sicher, dass der Vite-Server mit STRG+C beendet wird, und verwenden Sie dann die folgende PowerShell:
npm run build pac code pushÖffnen Sie die App über den bereitgestellten Link, um sie zu testen!
Problembehandlung
In diesem Abschnitt werden häufig auftretende Probleme behandelt, die beim Einrichten von Power Apps-Code-Apps mit Azure SQL-Datenbank auftreten können.
Azure SQL-Datenbankprobleme
Möglicherweise treten diese Probleme bei der Verwendung von Azure SQL-Datenbanken auf.
Verbindung mit Azure SQL-Datenbank nicht möglich
Symptome:
- Verbindungs-Timeout-Fehler
- Authentifizierungsfehler beim Herstellen einer Verbindung mit der SQL-Erweiterung von VS Code
Lösungen:
Firewalleinstellungen überprüfen:
- Navigieren Sie im Azure-Portal zu Ihrem SQL Server
- Wechseln sie zu Security → Networking
- Stellen Sie sicher, dass "Azure-Dienste und -Ressourcen für den Zugriff auf diesen Server zulassen" auf "Ja" festgelegt ist.
- Hinzufügen Ihrer aktuellen Client-IP-Adresse zu den Firewallregeln
Authentifizierungsmethode überprüfen:
- Stellen Sie sicher, dass Sie Microsoft Entra ID – Universal mit MFA-Unterstützung in VS Code verwenden
- Stellen Sie sicher, dass Sie sowohl im Azure-Portal als auch im VS-Code bei demselben Azure-Konto angemeldet sind
- Versuchen Sie, sich abzumelden und wieder einzuchecken, um Authentifizierungstoken zu aktualisieren.
Überprüfen der Netzwerkkonnektivität:
# Test connectivity to SQL Server Test-NetConnection -ComputerName "your-sql-server.database.windows.net" -Port 1433
SQL-Abfrageausführungsfehler
Symptome:
- Fehler aufgrund verweigerter Berechtigung beim Ausführen von SQL-Skripts
- Objekt enthält bereits Fehler.
Lösungen:
Berechtigungsprobleme:
- Stellen Sie sicher, dass Ihr Benutzerkonto als Microsoft Entra-Administrator für sql Server festgelegt ist.
- Überprüfen Sie, ob Sie über
db_owneroder entsprechende Berechtigungen für die Datenbank verfügen.
Existenzfehler des Objekts:
- Das SQL-Skript enthält
DROPAnweisungen – diese sind sicher, mehrmals auszuführen. - Wenn Einschränkungsfehler auftreten, führen Sie die Drop-Anweisungen zuerst einzeln aus.
- Das SQL-Skript enthält
Node.js- und npm-Probleme
Bei verwendung von Node.js und npm können diese Probleme auftreten.
Port 3000 wird bereits verwendet
Symptome:
- "EADDRINUSE: Adresse, die bereits verwendet wird :::3000"
- Der Vite-Server wird nicht gestartet.
Lösungen:
Vorhandenen Prozess beenden:
# Find process using port 3000 netstat -ano | findstr :3000 # Kill the process (replace PID with actual process ID) taskkill /PID [PID] /FAlternativer Port verwenden:
- Um einen anderen Port zu verwenden, aktualisieren Sie
vite.config.ts - Aktualisieren Sie die Power SDK-Konfiguration entsprechend
- Um einen anderen Port zu verwenden, aktualisieren Sie
Paketinstallationsfehler
Symptome:
- npm-Installationsfehler
- Modul nicht gefunden-Fehler
Lösungen:
Npm-Cache löschen:
npm cache clean --force npm installLöschen Sie node_modules, und installieren Sie es erneut:
Remove-Item -Recurse -Force node_modules Remove-Item package-lock.json npm installProbleme mit der Knotenversion:
# Check Node version node --version # Should be LTS version (18.x or 20.x)
Laufzeitverbindungsfehler
Symptome:
- "Daten konnten nicht geladen werden" in der React-App
- Verbindung verweigert-Fehler
Lösungen:
Überprüfen Sie die Power Platform-Verbindung:
- Überprüfen, ob die SQL Server-Verbindung in Power Platform funktioniert
- Testen der Verbindung in Power Apps
Zustimmungsprobleme:
- Stellen Sie sicher, dass Sie die Zustimmung erteilen, wenn die App zum ersten Mal geladen wird.
- Löschen sie den Browsercache, und versuchen Sie es erneut.
Umgebungskonflikt:
- Überprüfen, ob Sie die App in derselben Umgebung ausführen, in der die Verbindung erstellt wurde
- Überprüfen Sie, ob das Browserprofil Ihrem Power Platform-Konto entspricht.